Bug fixes.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5148 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-10-24 20:08:56 +00:00
parent 7f29148da0
commit b0bff411f1
9 changed files with 179 additions and 43 deletions

View File

@ -17,8 +17,8 @@
#ifdef _KERNEL_MODE #ifdef _KERNEL_MODE
#define spawn_thread spawn_kernel_thread #define spawn_thread spawn_kernel_thread
#define printf dprintf #define printf dprintf
#endif #endif
@ -107,6 +107,10 @@ PPPManager::PPPManager()
: fReportManager(fReportLock), : fReportManager(fReportLock),
fNextID(1) fNextID(1)
{ {
#if DEBUG
printf("PPPManager: Constructor\n");
#endif
fDeleterThread = spawn_thread(deleter_thread, "PPPManager: deleter_thread", fDeleterThread = spawn_thread(deleter_thread, "PPPManager: deleter_thread",
B_NORMAL_PRIORITY, this); B_NORMAL_PRIORITY, this);
resume_thread(fDeleterThread); resume_thread(fDeleterThread);
@ -116,6 +120,10 @@ PPPManager::PPPManager()
PPPManager::~PPPManager() PPPManager::~PPPManager()
{ {
#if DEBUG
printf("PPPManager: Destructor\n");
#endif
int32 tmp; int32 tmp;
send_data(fDeleterThread, 0, NULL, 0); send_data(fDeleterThread, 0, NULL, 0);
// notify deleter_thread that we are being destroyed // notify deleter_thread that we are being destroyed
@ -136,6 +144,10 @@ PPPManager::~PPPManager()
int32 int32
PPPManager::Stop(ifnet *ifp) PPPManager::Stop(ifnet *ifp)
{ {
#if DEBUG
printf("PPPManager: Stop(%s)\n", ifp ? ifp->if_name : "Unknown");
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ifp); interface_entry *entry = EntryFor(ifp);
@ -152,6 +164,10 @@ int32
PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst, PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
struct rtentry *rt0) struct rtentry *rt0)
{ {
#if DEBUG
printf("PPPManager: Output(%s)\n", ifp ? ifp->if_name : "Unknown");
#endif
if(dst->sa_family == AF_UNSPEC) if(dst->sa_family == AF_UNSPEC)
return B_ERROR; return B_ERROR;
@ -193,6 +209,10 @@ PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
int32 int32
PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data) PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
{ {
#if DEBUG
printf("PPPManager: Control(%s)\n", ifp ? ifp->if_name : "Unknown");
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ifp); interface_entry *entry = EntryFor(ifp);
if(!entry || entry->deleting) if(!entry || entry->deleting)
@ -226,6 +246,10 @@ interface_id
PPPManager::CreateInterface(const driver_settings *settings, PPPManager::CreateInterface(const driver_settings *settings,
interface_id parentID = PPP_UNDEFINED_INTERFACE_ID) interface_id parentID = PPP_UNDEFINED_INTERFACE_ID)
{ {
#if DEBUG
printf("PPPManager: CreateInterface()\n");
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
interface_entry *parentEntry = EntryFor(parentID); interface_entry *parentEntry = EntryFor(parentID);
@ -263,6 +287,10 @@ PPPManager::CreateInterface(const driver_settings *settings,
void void
PPPManager::DeleteInterface(interface_id ID) PPPManager::DeleteInterface(interface_id ID)
{ {
#if DEBUG
printf("PPPManager: DeleteInterface(%ld)\n", ID);
#endif
// This only marks the interface for deletion. // This only marks the interface for deletion.
// Our deleter_thread does the real work. // Our deleter_thread does the real work.
LockerHelper locker(fLock); LockerHelper locker(fLock);
@ -276,6 +304,10 @@ PPPManager::DeleteInterface(interface_id ID)
void void
PPPManager::RemoveInterface(interface_id ID) PPPManager::RemoveInterface(interface_id ID)
{ {
#if DEBUG
printf("PPPManager: RemoveInterface(%ld)\n", ID);
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
int32 index; int32 index;
@ -293,6 +325,10 @@ PPPManager::RemoveInterface(interface_id ID)
ifnet* ifnet*
PPPManager::RegisterInterface(interface_id ID) PPPManager::RegisterInterface(interface_id ID)
{ {
#if DEBUG
printf("PPPManager: RegisterInterface(%ld)\n", ID);
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ID); interface_entry *entry = EntryFor(ID);
@ -316,6 +352,11 @@ PPPManager::RegisterInterface(interface_id ID)
ifp->output = ppp_ifnet_output; ifp->output = ppp_ifnet_output;
ifp->ioctl = ppp_ifnet_ioctl; ifp->ioctl = ppp_ifnet_ioctl;
#if DEBUG
printf("PPPManager::DeleteInterface(): Created new ifnet: %s%d\n",
ifp->name, ifp->if_unit);
#endif
if_attach(ifp); if_attach(ifp);
return ifp; return ifp;
} }
@ -324,6 +365,10 @@ PPPManager::RegisterInterface(interface_id ID)
bool bool
PPPManager::UnregisterInterface(interface_id ID) PPPManager::UnregisterInterface(interface_id ID)
{ {
#if DEBUG
printf("PPPManager: UnregisterInterface(%ld)\n", ID);
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ID); interface_entry *entry = EntryFor(ID);
@ -342,6 +387,10 @@ PPPManager::UnregisterInterface(interface_id ID)
status_t status_t
PPPManager::Control(uint32 op, void *data, size_t length) PPPManager::Control(uint32 op, void *data, size_t length)
{ {
#if DEBUG
printf("PPPManager: Control(%ld)\n", op);
#endif
// this method is intended for use by userland applications // this method is intended for use by userland applications
switch(op) { switch(op) {
@ -454,6 +503,10 @@ PPPManager::Control(uint32 op, void *data, size_t length)
status_t status_t
PPPManager::ControlInterface(interface_id ID, uint32 op, void *data, size_t length) PPPManager::ControlInterface(interface_id ID, uint32 op, void *data, size_t length)
{ {
#if DEBUG
printf("PPPManager: ControlInterface(%ld)\n", ID);
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ID); interface_entry *entry = EntryFor(ID);
@ -468,6 +521,10 @@ int32
PPPManager::GetInterfaces(interface_id *interfaces, int32 count, PPPManager::GetInterfaces(interface_id *interfaces, int32 count,
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
{ {
#if DEBUG
printf("PPPManager: GetInterfaces()\n");
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
int32 item = 0; int32 item = 0;
@ -507,6 +564,10 @@ PPPManager::GetInterfaces(interface_id *interfaces, int32 count,
int32 int32
PPPManager::CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) PPPManager::CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
{ {
#if DEBUG
printf("PPPManager: CountInterfaces()\n");
#endif
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(filter == PPP_ALL_INTERFACES) if(filter == PPP_ALL_INTERFACES)
@ -544,6 +605,10 @@ PPPManager::CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFA
interface_entry* interface_entry*
PPPManager::EntryFor(interface_id ID, int32 *saveIndex = NULL) const PPPManager::EntryFor(interface_id ID, int32 *saveIndex = NULL) const
{ {
#if DEBUG
printf("PPPManager: EntryFor(%ld)\n", ID);
#endif
if(ID == PPP_UNDEFINED_INTERFACE_ID) if(ID == PPP_UNDEFINED_INTERFACE_ID)
return NULL; return NULL;
@ -567,6 +632,10 @@ PPPManager::EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const
if(!ifp) if(!ifp)
return NULL; return NULL;
#if DEBUG
printf("PPPManager: EntryFor(%s%d)\n", ifp->name, ifp->if_unit);
#endif
interface_entry *entry; interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) { for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index); entry = fEntries.ItemAt(index);

View File

@ -36,10 +36,6 @@ PPPoEDevice::PPPoEDevice(PPPInterface& interface, driver_parameter *settings)
printf("PPPoEDevice: Constructor\n"); printf("PPPoEDevice: Constructor\n");
if(!settings || !settings->parameters) if(!settings || !settings->parameters)
printf("PPPoEDevice::ctor: No settings!\n"); printf("PPPoEDevice::ctor: No settings!\n");
else if(settings->parameter_count > 0 && settings->parameters[0].value_count > 0)
printf("PPPoEDevice::ctor: Value0: %s\n", settings->parameters[0].values[0]);
else
printf("PPPoEDevice::ctor: No values!\n");
#endif #endif
memset(fPeer, 0xFF, sizeof(fPeer)); memset(fPeer, 0xFF, sizeof(fPeer));
@ -56,7 +52,8 @@ PPPoEDevice::PPPoEDevice(PPPInterface& interface, driver_parameter *settings)
ifnet *current = get_interfaces(); ifnet *current = get_interfaces();
for(; current; current = current->if_next) { for(; current; current = current->if_next) {
if(current->if_name && !strcmp(current->if_name, interfaceName)) { if(current->if_type == IFT_ETHER && current->if_name
&& !strcmp(current->if_name, interfaceName)) {
#if DEBUG #if DEBUG
printf("PPPoEDevice::ctor: found ethernet interface\n"); printf("PPPoEDevice::ctor: found ethernet interface\n");
#endif #endif

View File

@ -96,10 +96,16 @@ add_to(PPPInterface& mainInterface, PPPInterface *subInterface,
PPPoEDevice *device; PPPoEDevice *device;
bool success; bool success;
if(subInterface) { if(subInterface) {
#if DEBUG
printf("PPPoE: add_to(): Adding to subInterface\n");
#endif
device = new PPPoEDevice(*subInterface, settings); device = new PPPoEDevice(*subInterface, settings);
success = subInterface->SetDevice(device); success = subInterface->SetDevice(device);
} else } else {
device = new PPPoEDevice(mainInterface, settings); { #if DEBUG
printf("PPPoE: add_to(): Adding to mainInterface\n");
#endif
device = new PPPoEDevice(mainInterface, settings);
success = mainInterface.SetDevice(device); success = mainInterface.SetDevice(device);
} }

View File

@ -58,6 +58,8 @@ status_t redial_thread(void *data);
// other functions // other functions
status_t interface_deleter_thread(void *data); status_t interface_deleter_thread(void *data);
status_t call_open_event_thread(void *data);
status_t call_close_event_thread(void *data);
PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings, PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
@ -67,6 +69,8 @@ PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
fSettings(dup_driver_settings(settings)), fSettings(dup_driver_settings(settings)),
fIfnet(NULL), fIfnet(NULL),
fUpThread(-1), fUpThread(-1),
fOpenEventThread(-1),
fCloseEventThread(-1),
fRedialThread(-1), fRedialThread(-1),
fDialRetry(0), fDialRetry(0),
fDialRetriesLimit(0), fDialRetriesLimit(0),
@ -182,12 +186,12 @@ PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
PPPInterface::~PPPInterface() PPPInterface::~PPPInterface()
{ {
++fDeleteCounter;
#if DEBUG #if DEBUG
printf("PPPInterface: Destructor\n"); printf("PPPInterface: Destructor\n");
#endif #endif
++fDeleteCounter;
// make sure we are not accessible by any thread before we continue // make sure we are not accessible by any thread before we continue
UnregisterInterface(); UnregisterInterface();
@ -211,6 +215,8 @@ PPPInterface::~PPPInterface()
send_data_with_timeout(fRedialThread, 0, NULL, 0, 200); send_data_with_timeout(fRedialThread, 0, NULL, 0, 200);
// tell thread that we are being destroyed (200ms timeout) // tell thread that we are being destroyed (200ms timeout)
wait_for_thread(fRedialThread, &tmp); wait_for_thread(fRedialThread, &tmp);
wait_for_thread(fOpenEventThread, &tmp);
wait_for_thread(fCloseEventThread, &tmp);
while(CountChildren()) while(CountChildren())
delete ChildAt(0); delete ChildAt(0);
@ -459,7 +465,7 @@ bool
PPPInterface::SetDevice(PPPDevice *device) PPPInterface::SetDevice(PPPDevice *device)
{ {
#if DEBUG #if DEBUG
printf("PPPInterface: SetDevice()\n"); printf("PPPInterface: SetDevice(%p)\n", device);
#endif #endif
if(device && &device->Interface() != this) if(device && &device->Interface() != this)
@ -715,7 +721,7 @@ PPPInterface::SetAutoRedial(bool autoRedial = true)
printf("PPPInterface: SetAutoRedial(%s)\n", autoRedial ? "true" : "false"); printf("PPPInterface: SetAutoRedial(%s)\n", autoRedial ? "true" : "false");
#endif #endif
if(Mode() == PPP_CLIENT_MODE) if(Mode() != PPP_CLIENT_MODE)
return; return;
LockerHelper locker(fLock); LockerHelper locker(fLock);
@ -732,7 +738,6 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true)
#if DEBUG #if DEBUG
printf("PPPInterface: SetDialOnDemand(%s)\n", dialOnDemand ? "true" : "false"); printf("PPPInterface: SetDialOnDemand(%s)\n", dialOnDemand ? "true" : "false");
printf("PPPInterface::SetDialOnDemand(): %s\n", fDialOnDemand ? "true" : "false");
#endif #endif
// Only clients support DialOnDemand. // Only clients support DialOnDemand.
@ -749,10 +754,6 @@ PPPInterface::SetDialOnDemand(bool dialOnDemand = true)
fDialOnDemand = dialOnDemand; 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). // Do not allow changes when we are disconnected (only main interfaces).
// This would make no sense because // This would make no sense because
// - enabling: this cannot happen because hidden interfaces are deleted if they // - enabling: this cannot happen because hidden interfaces are deleted if they
@ -810,22 +811,31 @@ PPPInterface::Up()
// One thread has to do the real task while all other threads are observers. // One thread has to do the real task while all other threads are observers.
// Lock needs timeout because destructor could have locked the interface. // Lock needs timeout because destructor could have locked the interface.
while(!fLock.LockWithTimeout(100000) != B_NO_ERROR) while(fLock.LockWithTimeout(100000) != B_NO_ERROR)
if(fDeleteCounter > 0) if(fDeleteCounter > 0)
return false; return false;
if(fUpThread == -1) if(fUpThread == -1)
fUpThread = me; fUpThread = me;
ReportManager().EnableReports(PPP_CONNECTION_REPORT, me, PPP_WAIT_FOR_REPLY); ReportManager().EnableReports(PPP_CONNECTION_REPORT, me, PPP_WAIT_FOR_REPLY);
fLock.Unlock();
// fUpThread tells the state machine to go up // fUpThread/fRedialThread tells the state machine to go up (using a new thread
if(me == fUpThread || me == fRedialThread) // because we might not receive report messages otherwise)
StateMachine().OpenEvent(); if(me == fUpThread || me == fRedialThread) {
if(fOpenEventThread != -1) {
int32 tmp;
wait_for_thread(fOpenEventThread, &tmp);
}
fOpenEventThread = spawn_thread(call_open_event_thread,
"PPPInterface: call_open_event_thread", B_NORMAL_PRIORITY, this);
resume_thread(fOpenEventThread);
}
fLock.Unlock();
if(me == fRedialThread && me != fUpThread) if(me == fRedialThread && me != fUpThread)
return true; return true;
// the redial thread is doing a DialRetry in this case // the redial thread is doing a DialRetry in this case (fUpThread
// is waiting for new reports)
while(true) { while(true) {
if(IsUp()) { if(IsUp()) {
@ -1004,12 +1014,18 @@ PPPInterface::Down()
return true; return true;
ReportManager().EnableReports(PPP_CONNECTION_REPORT, find_thread(NULL)); ReportManager().EnableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
locker.UnlockNow();
thread_id sender; thread_id sender;
ppp_report_packet report; ppp_report_packet report;
StateMachine().CloseEvent(); if(fCloseEventThread != -1) {
int32 tmp;
wait_for_thread(fCloseEventThread, &tmp);
}
fCloseEventThread = spawn_thread(call_close_event_thread,
"PPPInterface: call_close_event_thread", B_NORMAL_PRIORITY, this);
resume_thread(fCloseEventThread);
locker.UnlockNow();
while(true) { while(true) {
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE) if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
@ -1351,10 +1367,6 @@ PPPInterface::RegisterInterface()
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(InitCheck() != B_OK)
return false;
// we cannot register if something is wrong
// only MainInterfaces get an ifnet // only MainInterfaces get an ifnet
if(IsMultilink() && Parent() && Parent()->RegisterInterface()) if(IsMultilink() && Parent() && Parent()->RegisterInterface())
return true; return true;
@ -1583,14 +1595,56 @@ redial_thread(void *data)
// which is only defined here (the real class is defined in the ppp interface module). // which is only defined here (the real class is defined in the ppp interface module).
class PPPManager { class PPPManager {
public: public:
PPPManager(PPPInterface *interface) PPPManager() {}
{ if(interface) delete interface; }
void Delete(PPPInterface *interface)
{ delete interface; }
void CallOpenEvent(PPPInterface *interface)
{
while(interface->fLock.LockWithTimeout(100000) != B_NO_ERROR)
if(interface->fDeleteCounter > 0)
return;
interface->CallOpenEvent();
interface->fOpenEventThread = -1;
interface->fLock.Unlock();
}
void CallCloseEvent(PPPInterface *interface)
{
while(interface->fLock.LockWithTimeout(100000) != B_NO_ERROR)
if(interface->fDeleteCounter > 0)
return;
interface->CallCloseEvent();
interface->fCloseEventThread = -1;
interface->fLock.Unlock();
}
}; };
status_t status_t
interface_deleter_thread(void *data) interface_deleter_thread(void *data)
{ {
PPPManager((PPPInterface*) data); PPPManager manager;
manager.Delete((PPPInterface*) data);
return B_OK;
}
status_t
call_open_event_thread(void *data)
{
PPPManager manager;
manager.CallOpenEvent((PPPInterface*) data);
return B_OK;
}
status_t
call_close_event_thread(void *data)
{
PPPManager manager;
manager.CallCloseEvent((PPPInterface*) data);
return B_OK; return B_OK;
} }

View File

@ -425,7 +425,7 @@ PPPStateMachine::UpFailedEvent()
Interface().Parent()->StateMachine().UpFailedEvent(Interface()); Interface().Parent()->StateMachine().UpFailedEvent(Interface());
NewPhase(PPP_DOWN_PHASE); NewPhase(PPP_DOWN_PHASE);
// tell DownEvent() that we do not need to redial // tell DownEvent() that it should not create a connection-lost-report
DownEvent(); DownEvent();
break; break;

View File

@ -187,6 +187,12 @@ class PPPInterface : public PPPLayer {
void CalculateInterfaceMTU(); void CalculateInterfaceMTU();
void CalculateBaudRate(); void CalculateBaudRate();
// these two methods are used by the open/close_event_threads
void CallOpenEvent()
{ StateMachine().OpenEvent(); }
void CallCloseEvent()
{ StateMachine().CloseEvent(); }
void Redial(uint32 delay); void Redial(uint32 delay);
// multilink methods // multilink methods
@ -199,7 +205,7 @@ class PPPInterface : public PPPLayer {
driver_settings *fSettings; driver_settings *fSettings;
struct ifnet *fIfnet; struct ifnet *fIfnet;
thread_id fUpThread; thread_id fUpThread, fOpenEventThread, fCloseEventThread;
thread_id fRedialThread; thread_id fRedialThread;
uint32 fDialRetry, fDialRetriesLimit; uint32 fDialRetry, fDialRetriesLimit;

View File

@ -52,7 +52,11 @@ PPPInterface::SetTo(interface_id ID)
fID = ID; fID = ID;
return Control(PPPC_GET_INTERFACE_INFO, &fInfo, sizeof(fInfo)); status_t error = Control(PPPC_GET_INTERFACE_INFO, &fInfo, sizeof(fInfo));
if(error != B_OK)
fID = PPP_UNDEFINED_INTERFACE_ID;
return error;
} }
@ -80,7 +84,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length) const
bool bool
PPPInterface::GetInterfaceInfo(ppp_interface_info *info) const PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
{ {
if(InitCheck() != B_OK || !info) if(InitCheck() != B_OK || !info)
return false; return false;

View File

@ -133,12 +133,12 @@ PPPManager::InterfaceWithSettings(const driver_settings *settings) const
interface_id id = PPP_UNDEFINED_INTERFACE_ID; interface_id id = PPP_UNDEFINED_INTERFACE_ID;
PPPInterface interface; PPPInterface interface;
ppp_interface_info info; ppp_interface_info_t info;
for(int32 index = 0; index < count; index++) { for(int32 index = 0; index < count; index++) {
interface.SetTo(interfaces[index]); interface.SetTo(interfaces[index]);
if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info) if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
&& equal_driver_settings(settings, info.settings)) { && equal_driver_settings(settings, info.info.settings)) {
id = interface.ID(); id = interface.ID();
break; break;
} }
@ -161,12 +161,12 @@ PPPManager::InterfaceWithUnit(int32 if_unit)
interface_id id = PPP_UNDEFINED_INTERFACE_ID; interface_id id = PPP_UNDEFINED_INTERFACE_ID;
PPPInterface interface; PPPInterface interface;
ppp_interface_info info; ppp_interface_info_t info;
for(int32 index = 0; index < count; index++) { for(int32 index = 0; index < count; index++) {
interface.SetTo(interfaces[index]); interface.SetTo(interfaces[index]);
if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info) if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
&& info.if_unit == if_unit) { && info.info.if_unit == if_unit) {
id = interface.ID(); id = interface.ID();
break; break;
} }

View File

@ -25,7 +25,7 @@ class PPPInterface {
status_t Control(uint32 op, void *data, size_t length) const; status_t Control(uint32 op, void *data, size_t length) const;
bool GetInterfaceInfo(ppp_interface_info *info) const; bool GetInterfaceInfo(ppp_interface_info_t *info) const;
bool Up() const; bool Up() const;
bool Down() const; bool Down() const;
@ -43,7 +43,7 @@ class PPPInterface {
interface_id fID; interface_id fID;
int fFD; int fFD;
ppp_interface_info fInfo; ppp_interface_info_t fInfo;
}; };