Some changes I did a long time ago. I think this also contains a fix for the last dead-lock I could find.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6857 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
6bef9fe1b8
commit
abf44d1a2b
@ -9,9 +9,12 @@
|
||||
|
||||
#include "PPPManager.h"
|
||||
#include <PPPControl.h>
|
||||
#include <KPPPModule.h>
|
||||
#include <KPPPUtils.h>
|
||||
#include <settings_tools.h>
|
||||
|
||||
#include <net_stack_driver.h>
|
||||
|
||||
#include <LockerHelper.h>
|
||||
|
||||
#include <cstdlib>
|
||||
@ -272,22 +275,7 @@ PPPManager::CreateInterfaceWithName(const char *name,
|
||||
if(!name)
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
|
||||
char path[B_PATH_NAME_LENGTH];
|
||||
sprintf(path, "pppidf/%s", name);
|
||||
// XXX: TODO: change base path to "/etc/ppp" when settings API supports it
|
||||
|
||||
void *handle = load_driver_settings(path);
|
||||
if(!handle)
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
|
||||
const driver_settings *settings = get_driver_settings(handle);
|
||||
if(!settings) {
|
||||
unload_driver_settings(handle);
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
}
|
||||
|
||||
ppp_interface_id result = _CreateInterface(name, settings, profile, parentID);
|
||||
unload_driver_settings(handle);
|
||||
ppp_interface_id result = _CreateInterface(name, NULL, profile, parentID);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -422,8 +410,24 @@ PPPManager::Control(uint32 op, void *data, size_t length)
|
||||
// this method is intended for use by userland applications
|
||||
|
||||
switch(op) {
|
||||
// case PPPC_CONTROL_MODULE: {
|
||||
// } break;
|
||||
case PPPC_CONTROL_MODULE: {
|
||||
if(length < sizeof(control_net_module_args) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
control_net_module_args *args = (control_net_module_args*) data;
|
||||
if(!args->name)
|
||||
return B_ERROR;
|
||||
|
||||
char name[B_PATH_NAME_LENGTH];
|
||||
strcpy(name, PPP_MODULES_PATH);
|
||||
strcat(name, args->name);
|
||||
ppp_module_info *module;
|
||||
if(get_module(name, (module_info**) &module) != B_OK
|
||||
|| !module->control)
|
||||
return B_ERROR;
|
||||
|
||||
return module->control(args->op, args->data, args->length);
|
||||
} break;
|
||||
|
||||
case PPPC_CREATE_INTERFACE: {
|
||||
if(length < sizeof(ppp_interface_description_info) || !data)
|
||||
@ -776,11 +780,11 @@ PPPManager::_CreateInterface(const char *name, const driver_settings *settings,
|
||||
entry->accessing = 1;
|
||||
entry->deleting = false;
|
||||
fEntries.AddItem(entry);
|
||||
// nothing bad can happen because we are in a locked section here
|
||||
// nothing bad can happen because we are in a locked section
|
||||
|
||||
new KPPPInterface(name, entry, id, settings, profile,
|
||||
parentEntry ? parentEntry->interface : NULL);
|
||||
// KPPPInterface will add itself to the entry (no need to do it here)
|
||||
// KPPPInterface will add itself to the entry (no need to do it here)
|
||||
if(entry->interface->InitCheck() != B_OK) {
|
||||
delete entry->interface;
|
||||
delete entry;
|
||||
@ -788,7 +792,7 @@ PPPManager::_CreateInterface(const char *name, const driver_settings *settings,
|
||||
}
|
||||
|
||||
locker.UnlockNow();
|
||||
// it is safe to access the manager from userland
|
||||
// it is safe to access the manager from userland now
|
||||
|
||||
if(!Report(PPP_MANAGER_REPORT, PPP_REPORT_INTERFACE_CREATED,
|
||||
&id, sizeof(ppp_interface_id))) {
|
||||
|
@ -37,20 +37,7 @@ IPCP::IPCP(KPPPInterface& interface, driver_parameter *settings)
|
||||
fTerminateID(0),
|
||||
fNextTimeout(0)
|
||||
{
|
||||
// reset configurations
|
||||
memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration));
|
||||
memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration));
|
||||
|
||||
// reset requests
|
||||
memset(&fLocalRequests, 0, sizeof(ipcp_requests));
|
||||
memset(&fPeerRequests, 0, sizeof(ipcp_requests));
|
||||
|
||||
// Parse settings:
|
||||
// "Local" and "Peer" describe each side's settings
|
||||
const driver_parameter *profile
|
||||
= Interface().Profile().SettingsFor("protocol", "ipcp");
|
||||
ParseSideRequests(get_parameter_with_name("Local", profile), PPP_LOCAL_SIDE);
|
||||
ParseSideRequests(get_parameter_with_name("Peer", profile), PPP_PEER_SIDE);
|
||||
ProfileChanged();
|
||||
}
|
||||
|
||||
|
||||
@ -92,6 +79,26 @@ IPCP::StackControl(uint32 op, void *data)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IPCP::ProfileChanged()
|
||||
{
|
||||
// reset configurations
|
||||
memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration));
|
||||
memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration));
|
||||
|
||||
// reset requests
|
||||
memset(&fLocalRequests, 0, sizeof(ipcp_requests));
|
||||
memset(&fPeerRequests, 0, sizeof(ipcp_requests));
|
||||
|
||||
// Parse settings:
|
||||
// "Local" and "Peer" describe each side's settings
|
||||
const driver_parameter *profile
|
||||
= Interface().Profile().SettingsFor("protocol", "ipcp");
|
||||
ParseSideRequests(get_parameter_with_name("Local", profile), PPP_LOCAL_SIDE);
|
||||
ParseSideRequests(get_parameter_with_name("Peer", profile), PPP_PEER_SIDE);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IPCP::Up()
|
||||
{
|
||||
|
@ -68,6 +68,8 @@ class IPCP : public KPPPProtocol {
|
||||
|
||||
virtual status_t StackControl(uint32 op, void *data);
|
||||
|
||||
virtual void ProfileChanged();
|
||||
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
|
@ -120,9 +120,7 @@ PAP::PAP(KPPPInterface& interface, driver_parameter *settings)
|
||||
fRequestID(0),
|
||||
fNextTimeout(0)
|
||||
{
|
||||
fUser[0] = fPassword[0] = 0;
|
||||
|
||||
ParseSettings(Interface().Profile().SettingsFor("authenticator", "pap"));
|
||||
ProfileChanged();
|
||||
}
|
||||
|
||||
|
||||
@ -141,6 +139,13 @@ PAP::InitCheck() const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PAP::ProfileChanged()
|
||||
{
|
||||
ParseSettings(Interface().Profile().SettingsFor("authenticator", "pap"));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PAP::Up()
|
||||
{
|
||||
|
@ -63,6 +63,8 @@ class PAP : public KPPPProtocol {
|
||||
pap_state State() const
|
||||
{ return fState; }
|
||||
|
||||
virtual void ProfileChanged();
|
||||
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
|
@ -15,6 +15,10 @@
|
||||
class PPPoEDevice;
|
||||
|
||||
|
||||
#define PPPoE_QUERY_REPORT_SIZE 2048
|
||||
#define PPPoE_QUERY_REPORT 'PoEQ'
|
||||
// the code value used for query reports
|
||||
|
||||
#define PPPoE_HEADER_SIZE 6
|
||||
// without ethernet header
|
||||
#define PPPoE_TIMEOUT 3000000
|
||||
@ -29,6 +33,16 @@ class PPPoEDevice;
|
||||
#define PPPoE_AC_NAME_KEY "ACName"
|
||||
#define PPPoE_SERVICE_NAME_KEY "ServiceName"
|
||||
|
||||
enum pppoe_ops {
|
||||
PPPoE_GET_INTERFACES,
|
||||
PPPoE_QUERY_SERVICES
|
||||
};
|
||||
|
||||
typedef struct pppoe_query_request {
|
||||
const char *interfaceName;
|
||||
thread_id receiver;
|
||||
} pppoe_query_request;
|
||||
|
||||
extern struct core_module_info *core;
|
||||
|
||||
|
||||
@ -48,6 +62,7 @@ typedef struct complete_pppoe_header {
|
||||
|
||||
|
||||
// defined in pppoe.cpp
|
||||
ifnet *FindPPPoEInterface(const char *name);
|
||||
uint32 NewHostUniq();
|
||||
void add_device(PPPoEDevice *device);
|
||||
void remove_device(PPPoEDevice *device);
|
||||
|
@ -49,6 +49,8 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
|
||||
fEthernetIfnet(NULL),
|
||||
fSessionID(0),
|
||||
fHostUniq(NewHostUniq()),
|
||||
fACName(NULL),
|
||||
fServiceName(NULL),
|
||||
fAttempts(0),
|
||||
fNextTimeout(0),
|
||||
fState(INITIAL)
|
||||
@ -74,14 +76,7 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
|
||||
fACName = get_parameter_value(PPPoE_AC_NAME_KEY, settings);
|
||||
fServiceName = get_parameter_value(PPPoE_SERVICE_NAME_KEY, settings);
|
||||
|
||||
ifnet *current = get_interfaces();
|
||||
for(; current; current = current->if_next) {
|
||||
if(current->if_type == IFT_ETHER && current->if_name
|
||||
&& !strcmp(current->if_name, interfaceName)) {
|
||||
fEthernetIfnet = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fEthernetIfnet = FindPPPoEInterface(interfaceName);
|
||||
|
||||
#if DEBUG
|
||||
if(!fEthernetIfnet)
|
||||
@ -312,6 +307,9 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber = 0)
|
||||
|
||||
locker.UnlockNow();
|
||||
|
||||
if(!packet)
|
||||
dprintf("PPPoEDevice::Send(): packet is NULL!\n");
|
||||
|
||||
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK) {
|
||||
dprintf("PPPoEDevice::Send(): EthernetIfnet()->output() failed!\n");
|
||||
DownEvent();
|
||||
@ -385,6 +383,9 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0)
|
||||
DiscoveryPacket reply(PADR);
|
||||
for(int32 index = 0; index < discovery.CountTags(); index++) {
|
||||
tag = discovery.TagAt(index);
|
||||
if(!tag)
|
||||
continue;
|
||||
|
||||
switch(tag->type) {
|
||||
case SERVICE_NAME:
|
||||
if(!hasServiceName && (!ServiceName()
|
||||
|
@ -14,12 +14,19 @@
|
||||
|
||||
#include <KPPPInterface.h>
|
||||
#include <KPPPModule.h>
|
||||
#include <KPPPUtils.h>
|
||||
#include <LockerHelper.h>
|
||||
|
||||
#include "PPPoEDevice.h"
|
||||
#include "DiscoveryPacket.h"
|
||||
|
||||
|
||||
typedef struct pppoe_query {
|
||||
ifnet *ethernetIfnet;
|
||||
uint32 hostUniq;
|
||||
thread_id receiver;
|
||||
} pppoe_query;
|
||||
|
||||
#define PPPoE_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pppoe"
|
||||
|
||||
struct core_module_info *core = NULL;
|
||||
@ -29,8 +36,64 @@ status_t std_ops(int32 op, ...);
|
||||
|
||||
static BLocker sLock;
|
||||
static TemplateList<PPPoEDevice*> *sDevices;
|
||||
static TemplateList<pppoe_query*> *sQueries;
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
SendQueryPacket(pppoe_query *query, DiscoveryPacket& discovery)
|
||||
{
|
||||
char data[PPPoE_QUERY_REPORT_SIZE];
|
||||
uint32 position = sizeof(uint32);
|
||||
pppoe_tag *acName = discovery.TagWithType(AC_NAME);
|
||||
|
||||
if(acName) {
|
||||
if(acName->length >= PPPoE_QUERY_REPORT_SIZE)
|
||||
return;
|
||||
|
||||
memcpy(data + position, acName->data, acName->length);
|
||||
position += acName->length;
|
||||
}
|
||||
|
||||
data[position++] = 0;
|
||||
|
||||
pppoe_tag *tag;
|
||||
for(int32 index = 0; index < discovery.CountTags(); index++) {
|
||||
tag = discovery.TagAt(index);
|
||||
if(tag && tag->type == SERVICE_NAME) {
|
||||
if(position + tag->length >= PPPoE_QUERY_REPORT_SIZE)
|
||||
return;
|
||||
|
||||
memcpy(data + position, tag->data, tag->length);
|
||||
position += tag->length;
|
||||
data[position++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(data, &position, sizeof(uint32));
|
||||
// add the total length
|
||||
|
||||
send_data_with_timeout(query->receiver, PPPoE_QUERY_REPORT, data,
|
||||
PPPoE_QUERY_REPORT_SIZE, 700000);
|
||||
}
|
||||
|
||||
|
||||
ifnet*
|
||||
FindPPPoEInterface(const char *name)
|
||||
{
|
||||
if(!name)
|
||||
return NULL;
|
||||
|
||||
ifnet *current = get_interfaces();
|
||||
for(; current; current = current->if_next) {
|
||||
if(current->if_type == IFT_ETHER && current->if_name
|
||||
&& !strcmp(current->if_name, name))
|
||||
return current;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32
|
||||
NewHostUniq()
|
||||
{
|
||||
@ -72,9 +135,36 @@ pppoe_input(struct mbuf *packet)
|
||||
ifnet *sourceIfnet = packet->m_pkthdr.rcvif;
|
||||
complete_pppoe_header *header = mtod(packet, complete_pppoe_header*);
|
||||
PPPoEDevice *device;
|
||||
pppoe_query *query;
|
||||
|
||||
LockerHelper locker(sLock);
|
||||
|
||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC
|
||||
&& header->pppoeHeader.length <= PPPoE_QUERY_REPORT_SIZE) {
|
||||
for(int32 index = 0; index < sDevices->CountItems(); index++) {
|
||||
query = sQueries->ItemAt(index);
|
||||
|
||||
if(query && query->ethernetIfnet == sourceIfnet) {
|
||||
if(header->pppoeHeader.code == PADO) {
|
||||
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||
if(discovery.InitCheck() != B_OK) {
|
||||
dprintf("PPPoE: received corrupted discovery packet!\n");
|
||||
m_freem(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
pppoe_tag *hostTag = discovery.TagWithType(HOST_UNIQ);
|
||||
if(hostTag && hostTag->length == 4
|
||||
&& *((uint32*)hostTag->data) == query->hostUniq) {
|
||||
SendQueryPacket(query, discovery);
|
||||
m_freem(packet);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int32 index = 0; index < sDevices->CountItems(); index++) {
|
||||
device = sDevices->ItemAt(index);
|
||||
|
||||
@ -96,6 +186,7 @@ pppoe_input(struct mbuf *packet)
|
||||
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||
if(discovery.InitCheck() != B_OK) {
|
||||
dprintf("PPPoE: received corrupted discovery packet!\n");
|
||||
m_freem(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -145,7 +236,59 @@ static
|
||||
status_t
|
||||
control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
return B_ERROR;
|
||||
switch(op) {
|
||||
case PPPoE_GET_INTERFACES: {
|
||||
int32 position = 0, count = 0;
|
||||
char *names = (char*) data;
|
||||
|
||||
ifnet *current = get_interfaces();
|
||||
for(; current; current = current->if_next) {
|
||||
if(current->if_type == IFT_ETHER && current->name) {
|
||||
if(position + strlen(current->name) + 1 > length)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
strcpy(names + position, current->name);
|
||||
position += strlen(current->name) + 1;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
case PPPoE_QUERY_SERVICES: {
|
||||
// XXX: as all modules are loaded on-demand we must wait for the results
|
||||
|
||||
if(!data || length != sizeof(pppoe_query_request))
|
||||
return B_ERROR;
|
||||
|
||||
pppoe_query_request *request = (pppoe_query_request*) data;
|
||||
|
||||
pppoe_query query;
|
||||
query.ethernetIfnet = FindPPPoEInterface(request->interfaceName);
|
||||
if(!query.ethernetIfnet)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
query.hostUniq = NewHostUniq();
|
||||
query.receiver = request->receiver;
|
||||
|
||||
sLock.Lock();
|
||||
sQueries->AddItem(&query);
|
||||
sLock.Unlock();
|
||||
|
||||
snooze(2000000);
|
||||
// wait two seconds for results
|
||||
|
||||
sLock.Lock();
|
||||
sQueries->RemoveItem(&query);
|
||||
sLock.Unlock();
|
||||
} break;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -176,9 +319,8 @@ std_ops(int32 op, ...)
|
||||
}
|
||||
|
||||
set_max_linkhdr(PPPoE_HEADER_SIZE + ETHER_HDR_LEN);
|
||||
|
||||
sDevices = new TemplateList<PPPoEDevice*>;
|
||||
|
||||
sQueries = new TemplateList<pppoe_query*>;
|
||||
sEthernet->set_pppoe_receiver(pppoe_input);
|
||||
|
||||
#if DEBUG
|
||||
|
@ -41,7 +41,8 @@ KPPPDevice::Control(uint32 op, void *data, size_t length)
|
||||
|
||||
ppp_device_info *info = (ppp_device_info*) data;
|
||||
memset(info, 0, sizeof(ppp_device_info_t));
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
if(Name())
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
info->MTU = MTU();
|
||||
info->inputTransferRate = InputTransferRate();
|
||||
info->outputTransferRate = OutputTransferRate();
|
||||
|
@ -93,7 +93,28 @@ KPPPInterface::KPPPInterface(const char *name, ppp_interface_entry *entry,
|
||||
{
|
||||
entry->interface = this;
|
||||
|
||||
fSettings = dup_driver_settings(settings);
|
||||
if(name) {
|
||||
// load settings from description file
|
||||
char path[B_PATH_NAME_LENGTH];
|
||||
sprintf(path, "pppidf/%s", name);
|
||||
// XXX: TODO: change base path to "/etc/ppp" when settings API supports it
|
||||
|
||||
void *handle = load_driver_settings(path);
|
||||
if(!handle) {
|
||||
fInitStatus = B_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fSettings = dup_driver_settings(get_driver_settings(handle));
|
||||
unload_driver_settings(handle);
|
||||
} else
|
||||
fSettings = dup_driver_settings(settings);
|
||||
// use the given settings
|
||||
|
||||
if(!fSettings) {
|
||||
fInitStatus = B_ERROR;
|
||||
return;
|
||||
}
|
||||
fProfile.LoadSettings(profile, fSettings);
|
||||
|
||||
// add internal modules
|
||||
@ -235,11 +256,12 @@ KPPPInterface::~KPPPInterface()
|
||||
fFirstProtocol = fFirstProtocol->NextProtocol();
|
||||
else
|
||||
delete FirstProtocol();
|
||||
// destructor removes protocol from list
|
||||
}
|
||||
|
||||
for(int32 index = 0; index < fModules.CountItems(); index++) {
|
||||
put_module(fModules.ItemAt(index));
|
||||
free(fModules.ItemAt(index));
|
||||
delete[] fModules.ItemAt(index);
|
||||
}
|
||||
|
||||
free_driver_settings(fSettings);
|
||||
@ -336,7 +358,8 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
|
||||
ppp_interface_info *info = (ppp_interface_info*) data;
|
||||
memset(info, 0, sizeof(ppp_interface_info_t));
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
if(Name())
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
if(Ifnet())
|
||||
info->if_unit = Ifnet()->if_unit;
|
||||
else
|
||||
@ -418,6 +441,16 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
ReportManager().DisableReports(request->type, request->thread);
|
||||
} break;
|
||||
|
||||
case PPPC_SET_PROFILE: {
|
||||
if(!data)
|
||||
return B_ERROR;
|
||||
|
||||
driver_settings *profile = (driver_settings*) data;
|
||||
fProfile.LoadSettings(profile, fSettings);
|
||||
|
||||
UpdateProfile();
|
||||
} break;
|
||||
|
||||
case PPPC_CONTROL_DEVICE: {
|
||||
if(length < sizeof(ppp_control_info) || !data)
|
||||
return B_ERROR;
|
||||
@ -1155,17 +1188,19 @@ KPPPInterface::LoadModule(const char *name, driver_parameter *parameter,
|
||||
if(!name || strlen(name) > B_FILE_NAME_LENGTH)
|
||||
return false;
|
||||
|
||||
char *module_name = (char*) malloc(B_PATH_NAME_LENGTH);
|
||||
char *moduleName = new char[B_PATH_NAME_LENGTH];
|
||||
|
||||
sprintf(module_name, "%s/%s", PPP_MODULES_PATH, name);
|
||||
sprintf(moduleName, "%s/%s", PPP_MODULES_PATH, name);
|
||||
|
||||
ppp_module_info *module;
|
||||
if(get_module(module_name, (module_info**) &module) != B_OK)
|
||||
if(get_module(moduleName, (module_info**) &module) != B_OK) {
|
||||
delete[] moduleName;
|
||||
return false;
|
||||
}
|
||||
|
||||
// add the module to the list of loaded modules
|
||||
// for putting them on our destruction
|
||||
fModules.AddItem(module_name);
|
||||
fModules.AddItem(moduleName);
|
||||
|
||||
return module->add_to(Parent() ? *Parent() : *this, this, parameter, type);
|
||||
}
|
||||
@ -1191,7 +1226,7 @@ KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
// we must pass the basic tests like:
|
||||
// do we have a device?
|
||||
// did we load all modules?
|
||||
if(InitCheck() != B_OK || !Device()) {
|
||||
if(InitCheck() != B_OK) {
|
||||
m_freem(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
@ -1444,6 +1479,16 @@ KPPPInterface::UnregisterInterface()
|
||||
}
|
||||
|
||||
|
||||
// called when profile changes
|
||||
void
|
||||
KPPPInterface::UpdateProfile()
|
||||
{
|
||||
KPPPLayer *layer = FirstProtocol();
|
||||
for(; layer; layer = layer->Next())
|
||||
layer->ProfileChanged();
|
||||
}
|
||||
|
||||
|
||||
// called by KPPPManager: manager routes stack ioctls to interface
|
||||
status_t
|
||||
KPPPInterface::StackControl(uint32 op, void *data)
|
||||
|
@ -187,6 +187,26 @@ KPPPLCP::AdditionalOverhead() const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KPPPLCP::ProfileChanged()
|
||||
{
|
||||
KPPPLCPExtension *extension;
|
||||
KPPPOptionHandler *handler;
|
||||
|
||||
for(int32 index = 0; index < CountLCPExtensions(); index++) {
|
||||
extension = LCPExtensionAt(index);
|
||||
if(extension)
|
||||
extension->ProfileChanged();
|
||||
}
|
||||
|
||||
for(int32 index = 0; index < CountOptionHandlers(); index++) {
|
||||
handler = OptionHandlerAt(index);
|
||||
if(handler)
|
||||
handler->ProfileChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
KPPPLCP::Up()
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ KPPPLCPExtension::KPPPLCPExtension(const char *name, uint8 code, KPPPInterface&
|
||||
if(name)
|
||||
fName = strdup(name);
|
||||
else
|
||||
fName = strdup("Unknown");
|
||||
fName = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -49,7 +49,8 @@ KPPPLCPExtension::Control(uint32 op, void *data, size_t length)
|
||||
|
||||
ppp_simple_handler_info *info = (ppp_simple_handler_info*) data;
|
||||
memset(info, 0, sizeof(ppp_simple_handler_info_t));
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
if(Name())
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
info->isEnabled = IsEnabled();
|
||||
} break;
|
||||
|
||||
@ -80,6 +81,13 @@ KPPPLCPExtension::StackControl(uint32 op, void *data)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KPPPLCPExtension::ProfileChanged()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KPPPLCPExtension::Reset()
|
||||
{
|
||||
|
@ -19,8 +19,8 @@
|
||||
KPPPLayer::KPPPLayer(const char *name, ppp_level level, uint32 overhead)
|
||||
: fInitStatus(B_OK),
|
||||
fOverhead(overhead),
|
||||
fLevel(level),
|
||||
fName(NULL),
|
||||
fLevel(level),
|
||||
fNext(NULL)
|
||||
{
|
||||
SetName(name);
|
||||
@ -40,6 +40,13 @@ KPPPLayer::InitCheck() const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KPPPLayer::ProfileChanged()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
|
||||
{
|
||||
@ -76,5 +83,5 @@ KPPPLayer::SetName(const char *name)
|
||||
if(name)
|
||||
fName = strdup(name);
|
||||
else
|
||||
fName = strdup("Unknown");
|
||||
fName = NULL;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ KPPPOptionHandler::KPPPOptionHandler(const char *name, uint8 type,
|
||||
if(name)
|
||||
fName = strdup(name);
|
||||
else
|
||||
fName = strdup("Unknown");
|
||||
fName = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -50,7 +50,8 @@ KPPPOptionHandler::Control(uint32 op, void *data, size_t length)
|
||||
|
||||
ppp_simple_handler_info *info = (ppp_simple_handler_info*) data;
|
||||
memset(info, 0, sizeof(ppp_simple_handler_info_t));
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
if(Name())
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
info->isEnabled = IsEnabled();
|
||||
} break;
|
||||
|
||||
@ -79,3 +80,10 @@ KPPPOptionHandler::StackControl(uint32 op, void *data)
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KPPPOptionHandler::ProfileChanged()
|
||||
{
|
||||
// do nothing by default
|
||||
}
|
||||
|
@ -55,6 +55,9 @@ void
|
||||
KPPPProfile::LoadSettings(const driver_settings *profile,
|
||||
driver_settings *interfaceSettings)
|
||||
{
|
||||
if(fSettings != Interface().Settings())
|
||||
free_driver_settings(fSettings);
|
||||
|
||||
// -----------------------------
|
||||
// given profile
|
||||
// -----------------------------
|
||||
|
@ -34,7 +34,7 @@ KPPPProtocol::KPPPProtocol(const char *name, ppp_phase activationPhase,
|
||||
if(type)
|
||||
fType = strdup(type);
|
||||
else
|
||||
fType = strdup("Unknown");
|
||||
fType = NULL;
|
||||
|
||||
const char *sideString = get_parameter_value("side", settings);
|
||||
if(sideString)
|
||||
@ -66,8 +66,10 @@ KPPPProtocol::Control(uint32 op, void *data, size_t length)
|
||||
|
||||
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);
|
||||
if(Name())
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
if(Type())
|
||||
strncpy(info->type, Type(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
info->activationPhase = ActivationPhase();
|
||||
info->addressFamily = AddressFamily();
|
||||
info->flags = Flags();
|
||||
|
@ -1538,7 +1538,8 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
dprintf("KPPPSM::RCREvent(): OH=%s\n", optionHandler->Name());
|
||||
dprintf("KPPPSM::RCREvent(): OH=%s\n",
|
||||
optionHandler->Name() ? optionHandler->Name() : "Unknown");
|
||||
#endif
|
||||
result = optionHandler->ParseRequest(request, index, nak, reject);
|
||||
|
||||
|
@ -42,7 +42,7 @@ _KPPPAuthenticationHandler::NextAuthenticator(const KPPPProtocol *start,
|
||||
KPPPProtocol *current = start ? start->NextProtocol() : Interface().FirstProtocol();
|
||||
|
||||
for(; current; current = current->NextProtocol()) {
|
||||
if(!strcasecmp(current->Type(), AUTHENTICATOR_TYPE_STRING)
|
||||
if(current->Type() && !strcasecmp(current->Type(), AUTHENTICATOR_TYPE_STRING)
|
||||
&& current->OptionHandler() && current->Side() == side)
|
||||
return current;
|
||||
}
|
||||
@ -136,7 +136,7 @@ _KPPPAuthenticationHandler::ParseNak(const KPPPConfigurePacket& nak)
|
||||
|
||||
fPeerAuthenticatorRejected = true;
|
||||
KPPPProtocol *authenticator = Interface().ProtocolFor(ntohs(item->protocolNumber));
|
||||
if(authenticator
|
||||
if(authenticator && authenticator->Type()
|
||||
&& !strcasecmp(authenticator->Type(), AUTHENTICATOR_TYPE_STRING)
|
||||
&& authenticator->OptionHandler())
|
||||
fSuggestedPeerAuthenticator = authenticator;
|
||||
@ -199,8 +199,8 @@ _KPPPAuthenticationHandler::ParseRequest(const KPPPConfigurePacket& request,
|
||||
|
||||
// try to find the requested protocol
|
||||
fLocalAuthenticator = Interface().ProtocolFor(ntohs(item->protocolNumber));
|
||||
if(fLocalAuthenticator &&
|
||||
!strcasecmp(fLocalAuthenticator->Type(), AUTHENTICATOR_TYPE_STRING)
|
||||
if(fLocalAuthenticator && fLocalAuthenticator->Type()
|
||||
&& !strcasecmp(fLocalAuthenticator->Type(), AUTHENTICATOR_TYPE_STRING)
|
||||
&& fLocalAuthenticator->OptionHandler())
|
||||
return fLocalAuthenticator->OptionHandler()->ParseRequest(request, index,
|
||||
nak, reject);
|
||||
|
@ -194,7 +194,7 @@ class KPPPInterface : public KPPPLayer {
|
||||
// saves the returned ifnet structure
|
||||
bool UnregisterInterface();
|
||||
|
||||
void SetName(const char *name);
|
||||
void UpdateProfile();
|
||||
|
||||
status_t StackControl(uint32 op, void *data);
|
||||
// stack routes ioctls to interface
|
||||
|
@ -74,6 +74,8 @@ class KPPPLCP : public KPPPProtocol {
|
||||
uint32 AdditionalOverhead() const;
|
||||
// the overhead caused by the target, the device, and the interface
|
||||
|
||||
virtual void ProfileChanged();
|
||||
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
|
@ -46,6 +46,8 @@ class KPPPLCPExtension {
|
||||
virtual status_t StackControl(uint32 op, void *data);
|
||||
// called by netstack (forwarded by KPPPInterface)
|
||||
|
||||
virtual void ProfileChanged();
|
||||
|
||||
virtual status_t Receive(struct mbuf *packet, uint8 code) = 0;
|
||||
|
||||
virtual void Reset();
|
||||
|
@ -34,6 +34,8 @@ class KPPPLayer {
|
||||
KPPPLayer *Next() const
|
||||
{ return fNext; }
|
||||
|
||||
virtual void ProfileChanged();
|
||||
|
||||
virtual bool Up() = 0;
|
||||
virtual bool Down() = 0;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "interfaces/ppp"
|
||||
|
||||
#define PPP_UNDEFINED_INTERFACE_ID 0
|
||||
// create_interface() returns this value on failure
|
||||
// CreateInterface() returns this value on failure
|
||||
|
||||
|
||||
class KPPPInterface;
|
||||
|
@ -48,6 +48,8 @@ class KPPPOptionHandler {
|
||||
virtual status_t StackControl(uint32 op, void *data);
|
||||
// called by netstack (forwarded by KPPPInterface)
|
||||
|
||||
virtual void ProfileChanged();
|
||||
|
||||
// we want to send a configure request or we received a reply
|
||||
virtual status_t AddToRequest(KPPPConfigurePacket& request) = 0;
|
||||
virtual status_t ParseNak(const KPPPConfigurePacket& nak) = 0;
|
||||
|
@ -18,7 +18,7 @@ class KPPPProtocol;
|
||||
|
||||
|
||||
// helper functions
|
||||
bool IsProtocolAllowed(const KPPPProtocol& protocol);
|
||||
extern bool IsProtocolAllowed(const KPPPProtocol& protocol);
|
||||
|
||||
// the list template does not support iterating over each item :(
|
||||
// this template iterates over each item in an indexed list
|
||||
@ -35,10 +35,10 @@ ForEachItem(_LIST& list, _FUNCTION function)
|
||||
// These are very simple send/receive_data functions with a timeout
|
||||
// and there is a race condition beween has_data() and send/receive_data().
|
||||
// Timeouts in ms.
|
||||
status_t send_data_with_timeout(thread_id thread, int32 code, void *buffer,
|
||||
size_t buffer_size, uint32 timeout);
|
||||
status_t receive_data_with_timeout(thread_id *sender, int32 *code, void *buffer,
|
||||
extern status_t send_data_with_timeout(thread_id thread, int32 code, void *buffer,
|
||||
size_t buffer_size, uint32 timeout);
|
||||
extern status_t receive_data_with_timeout(thread_id *sender, int32 *code,
|
||||
void *buffer, size_t buffer_size, uint32 timeout);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -52,9 +52,10 @@ enum ppp_control_ops {
|
||||
PPPC_SET_DIAL_ON_DEMAND,
|
||||
PPPC_SET_AUTO_REDIAL,
|
||||
PPPC_HAS_INTERFACE_SETTINGS,
|
||||
PPPC_SET_PROFILE,
|
||||
|
||||
// handler access
|
||||
PPPC_CONTROL_DEVICE,
|
||||
PPPC_CONTROL_DEVICE = PPP_INTERFACE_OPS_START + 0xFF,
|
||||
PPPC_CONTROL_PROTOCOL,
|
||||
PPPC_CONTROL_OPTION_HANDLER,
|
||||
PPPC_CONTROL_LCP_EXTENSION,
|
||||
|
@ -12,19 +12,23 @@
|
||||
|
||||
|
||||
// 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);
|
||||
extern driver_settings *dup_driver_settings(const driver_settings *settings);
|
||||
extern 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);
|
||||
bool equal_interface_settings(const driver_settings *lhs, const driver_settings *rhs);
|
||||
extern bool equal_driver_settings(const driver_settings *lhs,
|
||||
const driver_settings *rhs);
|
||||
extern bool equal_driver_parameters(const driver_parameter *lhs,
|
||||
const driver_parameter *rhs);
|
||||
extern bool equal_interface_settings(const driver_settings *lhs,
|
||||
const driver_settings *rhs);
|
||||
// this compares only the relevant parts of the interface settings
|
||||
|
||||
ppp_side get_side_string_value(const char *sideString, ppp_side unknownValue);
|
||||
bool get_boolean_value(const char *string, bool unknownValue);
|
||||
const driver_parameter *get_parameter_with_name(const char *name,
|
||||
extern ppp_side get_side_string_value(const char *sideString, ppp_side unknownValue);
|
||||
extern bool get_boolean_value(const char *string, bool unknownValue);
|
||||
extern const driver_parameter *get_parameter_with_name(const char *name,
|
||||
const driver_settings *settings);
|
||||
extern const char *get_settings_value(const char *name,
|
||||
const driver_settings *settings);
|
||||
const char *get_settings_value(const char *name, const driver_settings *settings);
|
||||
|
||||
|
||||
inline
|
||||
|
@ -134,6 +134,16 @@ PPPInterface::HasSettings(const driver_settings *settings) const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PPPInterface::SetProfile(const driver_settings *profile) const
|
||||
{
|
||||
if(InitCheck() != B_OK || !profile)
|
||||
return;
|
||||
|
||||
Control(PPPC_SET_PROFILE, const_cast<driver_settings*>(profile), 0);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::Up() const
|
||||
{
|
||||
|
@ -36,6 +36,8 @@ class PPPInterface {
|
||||
bool GetInterfaceInfo(ppp_interface_info_t *info) const;
|
||||
bool HasSettings(const driver_settings *settings) const;
|
||||
|
||||
void SetProfile(const driver_settings *profile) const;
|
||||
|
||||
bool Up() const;
|
||||
bool Down() const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user