Fixed bugs.

IPCP: fixed setting of local and peer address (in_control).
Renamed some variables to comply with our style defs.
Fixed a dead-lock in ppp interface and libkernelppp.a.

TODO:
Unfortunately, our stack does not want to ping the remote host. :(
I do not know if this is my fault or a problem with our stack.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5487 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-11-26 20:16:10 +00:00
parent 280533f33d
commit 93a59056e2
19 changed files with 313 additions and 190 deletions

View File

@ -23,14 +23,14 @@
#endif
static const char ppp_if_name_base[] = "ppp";
static const char sPPPIfNameBase[] = "ppp";
static
status_t
interface_up_thread(void *data)
{
interface_entry *entry = (interface_entry*) data;
ppp_interface_entry *entry = (ppp_interface_entry*) data;
entry->interface->Up();
--entry->accessing;
@ -41,7 +41,7 @@ interface_up_thread(void *data)
static
status_t
bring_interface_up(interface_entry *entry)
bring_interface_up(ppp_interface_entry *entry)
{
thread_id upThread = spawn_thread(interface_up_thread,
"PPPManager: up_thread", B_NORMAL_PRIORITY, entry);
@ -56,7 +56,7 @@ static
status_t
interface_down_thread(void *data)
{
interface_entry *entry = (interface_entry*) data;
ppp_interface_entry *entry = (ppp_interface_entry*) data;
entry->interface->Down();
--entry->accessing;
@ -68,7 +68,7 @@ interface_down_thread(void *data)
static
status_t
bring_interface_down(interface_entry *entry)
bring_interface_down(ppp_interface_entry *entry)
{
#if DOWN_AS_THREAD
thread_id downThread = spawn_thread(interface_down_thread,
@ -139,7 +139,7 @@ PPPManager::~PPPManager()
net_remove_timer(fPulseTimer);
// now really delete the interfaces (the deleter_thread is not running)
interface_entry *entry;
ppp_interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
if(entry)
@ -158,9 +158,11 @@ PPPManager::Stop(ifnet *ifp)
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ifp);
if(!entry)
ppp_interface_entry *entry = EntryFor(ifp);
if(!entry) {
printf("PPPManager: Stop(): Could not find interface!\n");
return B_ERROR;
}
DeleteInterface(entry->interface->ID());
@ -180,9 +182,11 @@ PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
return B_ERROR;
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ifp);
if(!entry)
ppp_interface_entry *entry = EntryFor(ifp);
if(!entry) {
printf("PPPManager: Output(): Could not find interface!\n");
return B_ERROR;
}
++entry->accessing;
locker.UnlockNow();
@ -225,9 +229,11 @@ PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
#endif
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ifp);
if(!entry || entry->deleting)
ppp_interface_entry *entry = EntryFor(ifp);
if(!entry || entry->deleting) {
printf("PPPManager: Control(): Could not find interface!\n");
return B_ERROR;
}
int32 status = B_OK;
++entry->accessing;
@ -264,42 +270,45 @@ PPPManager::CreateInterface(const driver_settings *settings,
LockerHelper locker(fLock);
interface_entry *parentEntry = EntryFor(parentID);
ppp_interface_entry *parentEntry = EntryFor(parentID);
if(parentID != PPP_UNDEFINED_INTERFACE_ID && !parentEntry)
return PPP_UNDEFINED_INTERFACE_ID;
interface_id id = NextID();
interface_entry *entry = new interface_entry;
ppp_interface_entry *entry = new ppp_interface_entry;
entry->accessing = 1;
entry->deleting = false;
fRegisterRequestor = PPP_UNDEFINED_INTERFACE_ID;
entry->interface = new PPPInterface(id, settings,
parentEntry ? parentEntry->interface : NULL);
fEntries.AddItem(entry);
// nothing bad can happen because we are in a locked section here
new PPPInterface(entry, id, settings, parentEntry ? parentEntry->interface : NULL);
// PPPInterface will add itself to the entry (no need to do it here)
if(entry->interface->InitCheck() != B_OK) {
delete entry->interface;
delete entry;
return PPP_UNDEFINED_INTERFACE_ID;
}
fEntries.AddItem(entry);
if(fRegisterRequestor == id)
entry->interface->RegisterInterface();
locker.UnlockNow();
if(!Report(PPP_MANAGER_REPORT, PPP_REPORT_INTERFACE_CREATED,
&id, sizeof(interface_id))) {
DeleteInterface(id);
id = PPP_UNDEFINED_INTERFACE_ID;
--entry->accessing;
return PPP_UNDEFINED_INTERFACE_ID;
}
// notify handlers that interface has been created and they can initialize it now
entry->interface->StateMachine().DownProtocols();
entry->interface->StateMachine().ResetLCPHandlers();
--entry->accessing;
return id;
}
void
bool
PPPManager::DeleteInterface(interface_id ID)
{
#if DEBUG
@ -310,14 +319,23 @@ PPPManager::DeleteInterface(interface_id ID)
// Our deleter_thread does the real work.
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ID);
ppp_interface_entry *entry = EntryFor(ID);
if(!entry)
return false;
++entry->accessing;
locker.UnlockNow();
entry->interface->Down();
if(entry)
entry->deleting = true;
entry->deleting = true;
--entry->accessing;
return true;
}
void
bool
PPPManager::RemoveInterface(interface_id ID)
{
#if DEBUG
@ -327,14 +345,16 @@ PPPManager::RemoveInterface(interface_id ID)
LockerHelper locker(fLock);
int32 index;
interface_entry *entry = EntryFor(ID, &index);
ppp_interface_entry *entry = EntryFor(ID, &index);
if(!entry || entry->deleting)
return;
return false;
UnregisterInterface(ID);
delete entry;
fEntries.RemoveItem(index);
return true;
}
@ -347,9 +367,7 @@ PPPManager::RegisterInterface(interface_id ID)
LockerHelper locker(fLock);
fRegisterRequestor = ID;
interface_entry *entry = EntryFor(ID);
ppp_interface_entry *entry = EntryFor(ID);
if(!entry || entry->deleting)
return NULL;
@ -361,7 +379,7 @@ PPPManager::RegisterInterface(interface_id ID)
memset(ifp, 0, sizeof(ifnet));
ifp->devid = -1;
ifp->if_type = IFT_PPP;
ifp->name = ppp_if_name_base;
ifp->name = sPPPIfNameBase;
ifp->if_unit = FindUnit();
ifp->if_flags = IFF_POINTOPOINT;
ifp->rx_thread = ifp->tx_thread = -1;
@ -389,10 +407,7 @@ PPPManager::UnregisterInterface(interface_id ID)
LockerHelper locker(fLock);
if(fRegisterRequestor == ID)
fRegisterRequestor = PPP_UNDEFINED_INTERFACE_ID;
interface_entry *entry = EntryFor(ID);
ppp_interface_entry *entry = EntryFor(ID);
if(!entry)
return false;
@ -432,7 +447,8 @@ PPPManager::Control(uint32 op, void *data, size_t length)
if(length != sizeof(interface_id) || !data)
return B_ERROR;
DeleteInterface(*(interface_id*)data);
if(!DeleteInterface(*(interface_id*)data))
return B_ERROR;
break;
case PPPC_BRING_INTERFACE_UP: {
@ -441,7 +457,7 @@ PPPManager::Control(uint32 op, void *data, size_t length)
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(*(interface_id*)data);
ppp_interface_entry *entry = EntryFor(*(interface_id*)data);
if(!entry || entry->deleting)
return B_BAD_INDEX;
@ -456,7 +472,7 @@ PPPManager::Control(uint32 op, void *data, size_t length)
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(*(interface_id*)data);
ppp_interface_entry *entry = EntryFor(*(interface_id*)data);
if(!entry || entry->deleting)
return B_BAD_INDEX;
@ -472,7 +488,7 @@ PPPManager::Control(uint32 op, void *data, size_t length)
LockerHelper locker(fLock);
ppp_control_info *control = (ppp_control_info*) data;
interface_entry *entry = EntryFor(control->index);
ppp_interface_entry *entry = EntryFor(control->index);
if(!entry || entry->deleting)
return B_BAD_INDEX;
@ -534,7 +550,7 @@ PPPManager::ControlInterface(interface_id ID, uint32 op, void *data, size_t leng
LockerHelper locker(fLock);
interface_entry *entry = EntryFor(ID);
ppp_interface_entry *entry = EntryFor(ID);
if(entry && !entry->deleting)
return entry->interface->Control(op, data, length);
@ -554,7 +570,7 @@ PPPManager::GetInterfaces(interface_id *interfaces, int32 count,
int32 item = 0;
// the current item in 'interfaces' (also the number of ids copied)
interface_entry *entry;
ppp_interface_entry *entry;
for(int32 index = 0; item < count && index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
@ -599,7 +615,7 @@ PPPManager::CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFA
return fEntries.CountItems();
int32 count = 0;
interface_entry *entry;
ppp_interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
@ -627,7 +643,7 @@ PPPManager::CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFA
}
interface_entry*
ppp_interface_entry*
PPPManager::EntryFor(interface_id ID, int32 *saveIndex = NULL) const
{
#if DEBUG
@ -637,7 +653,7 @@ PPPManager::EntryFor(interface_id ID, int32 *saveIndex = NULL) const
if(ID == PPP_UNDEFINED_INTERFACE_ID)
return NULL;
interface_entry *entry;
ppp_interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
if(entry && entry->interface->ID() == ID) {
@ -651,7 +667,7 @@ PPPManager::EntryFor(interface_id ID, int32 *saveIndex = NULL) const
}
interface_entry*
ppp_interface_entry*
PPPManager::EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const
{
if(!ifp)
@ -661,7 +677,7 @@ PPPManager::EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const
printf("PPPManager: EntryFor(%s%d)\n", ifp->name, ifp->if_unit);
#endif
interface_entry *entry;
ppp_interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
if(entry && entry->interface->Ifnet() == ifp) {
@ -689,7 +705,7 @@ PPPManager::FindUnit() const
// Find the smallest unused unit.
int32 *units = new int32[fEntries.CountItems()];
interface_entry *entry;
ppp_interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
if(entry && entry->interface->Ifnet())
@ -718,7 +734,7 @@ PPPManager::DeleterThreadEvent()
LockerHelper locker(fLock);
// delete and remove marked interfaces
interface_entry *entry;
ppp_interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
if(!entry) {
@ -742,7 +758,7 @@ PPPManager::Pulse()
{
LockerHelper locker(fLock);
interface_entry *entry;
ppp_interface_entry *entry;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
if(entry)

View File

@ -20,13 +20,6 @@ extern int ppp_ifnet_output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
extern int ppp_ifnet_ioctl(ifnet *ifp, ulong cmd, caddr_t data);
typedef struct interface_entry {
PPPInterface *interface;
vint32 accessing;
bool deleting;
} interface_entry;
class PPPManager {
public:
PPPManager();
@ -39,8 +32,8 @@ class PPPManager {
interface_id CreateInterface(const driver_settings *settings,
interface_id parentID = PPP_UNDEFINED_INTERFACE_ID);
void DeleteInterface(interface_id ID);
void RemoveInterface(interface_id ID);
bool DeleteInterface(interface_id ID);
bool RemoveInterface(interface_id ID);
ifnet *RegisterInterface(interface_id ID);
bool UnregisterInterface(interface_id ID);
@ -59,8 +52,8 @@ class PPPManager {
{ return ReportManager().Report(type, code, data, length); }
// returns false if reply was bad (or an error occured)
interface_entry *EntryFor(interface_id ID, int32 *saveIndex = NULL) const;
interface_entry *EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const;
ppp_interface_entry *EntryFor(interface_id ID, int32 *saveIndex = NULL) const;
ppp_interface_entry *EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const;
interface_id NextID()
{ return (interface_id) atomic_add((int32*) &fNextID, 1); }
@ -74,8 +67,8 @@ class PPPManager {
private:
BLocker fLock, fReportLock;
PPPReportManager fReportManager;
List<interface_entry*> fEntries;
interface_id fNextID, fRegisterRequestor;
List<ppp_interface_entry*> fEntries;
interface_id fNextID;
thread_id fDeleterThread, fPulseTimer;
};

View File

@ -16,14 +16,14 @@
status_t std_ops(int32 op, ...);
struct core_module_info *core = NULL;
static PPPManager *manager = NULL;
static PPPManager *sManager = NULL;
int
ppp_ifnet_stop(ifnet *ifp)
{
if(manager)
return manager->Stop(ifp);
if(sManager)
return sManager->Stop(ifp);
else
return B_ERROR;
}
@ -33,8 +33,8 @@ int
ppp_ifnet_output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
struct rtentry *rt0)
{
if(manager)
return manager->Output(ifp, buf, dst, rt0);
if(sManager)
return sManager->Output(ifp, buf, dst, rt0);
else
return B_ERROR;
}
@ -43,8 +43,8 @@ ppp_ifnet_output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
int
ppp_ifnet_ioctl(ifnet *ifp, ulong cmd, caddr_t data)
{
if(manager)
return manager->Control(ifp, cmd, data);
if(sManager)
return sManager->Control(ifp, cmd, data);
else
return B_ERROR;
}
@ -57,7 +57,7 @@ ppp_start(void *cpp)
if(cpp)
core = (core_module_info*) cpp;
manager = new PPPManager;
sManager = new PPPManager;
return B_OK;
}
@ -67,8 +67,8 @@ static
int
ppp_stop()
{
delete manager;
manager = NULL;
delete sManager;
sManager = NULL;
return B_OK;
}
@ -79,8 +79,8 @@ static
status_t
ppp_control(uint32 op, void *data, size_t length)
{
if(manager)
return manager->Control(op, data, length);
if(sManager)
return sManager->Control(op, data, length);
else
return B_ERROR;
}
@ -90,28 +90,32 @@ static
interface_id
CreateInterface(const driver_settings *settings, interface_id parent)
{
if(manager)
return manager->CreateInterface(settings, parent);
if(sManager)
return sManager->CreateInterface(settings, parent);
else
return PPP_UNDEFINED_INTERFACE_ID;
}
static
void
bool
DeleteInterface(interface_id ID)
{
if(manager)
manager->DeleteInterface(ID);
if(sManager)
return sManager->DeleteInterface(ID);
else
return false;
}
static
void
bool
RemoveInterface(interface_id ID)
{
if(manager)
manager->RemoveInterface(ID);
if(sManager)
return sManager->RemoveInterface(ID);
else
return false;
}
@ -119,8 +123,8 @@ static
ifnet*
RegisterInterface(interface_id ID)
{
if(manager)
return manager->RegisterInterface(ID);
if(sManager)
return sManager->RegisterInterface(ID);
else
return NULL;
}
@ -130,8 +134,8 @@ static
bool
UnregisterInterface(interface_id ID)
{
if(manager)
return manager->UnregisterInterface(ID);
if(sManager)
return sManager->UnregisterInterface(ID);
else
return false;
}
@ -141,8 +145,8 @@ static
status_t
ControlInterface(interface_id ID, uint32 op, void *data, size_t length)
{
if(manager)
return manager->ControlInterface(ID, op, data, length);
if(sManager)
return sManager->ControlInterface(ID, op, data, length);
else
return B_ERROR;
}
@ -153,8 +157,8 @@ int32
GetInterfaces(interface_id *interfaces, int32 count,
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
{
if(manager)
return manager->GetInterfaces(interfaces, count, filter);
if(sManager)
return sManager->GetInterfaces(interfaces, count, filter);
else
return 0;
}
@ -164,8 +168,8 @@ static
int32
CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
{
if(manager)
return manager->CountInterfaces(filter);
if(sManager)
return sManager->CountInterfaces(filter);
else
return 0;
}
@ -175,8 +179,8 @@ static
void
EnableReports(ppp_report_type type, thread_id thread, int32 flags = PPP_NO_FLAGS)
{
if(manager)
manager->ReportManager().EnableReports(type, thread, flags);
if(sManager)
sManager->ReportManager().EnableReports(type, thread, flags);
}
@ -184,8 +188,8 @@ static
void
DisableReports(ppp_report_type type, thread_id thread)
{
if(manager)
manager->ReportManager().DisableReports(type, thread);
if(sManager)
sManager->ReportManager().DisableReports(type, thread);
}
@ -193,8 +197,8 @@ static
bool
DoesReport(ppp_report_type type, thread_id thread)
{
if(manager)
return manager->ReportManager().DoesReport(type, thread);
if(sManager)
return sManager->ReportManager().DoesReport(type, thread);
else
return false;
}

View File

@ -12,7 +12,8 @@
#include <LockerHelper.h>
#include <cstring>
#include <netinet/in.h>
//#include <netinet/in.h>
#include <netinet/in_var.h>
#include <core_funcs.h>
#include <sys/sockio.h>
@ -59,8 +60,6 @@ IPCP::IPCP(PPPInterface& interface, driver_parameter *settings)
else if(!strcasecmp(settings->parameters[index].name, "Peer"))
ParseSideRequests(&settings->parameters[index], PPP_PEER_SIDE);
}
UpdateAddresses();
}
@ -69,6 +68,38 @@ IPCP::~IPCP()
}
status_t
IPCP::StackControl(uint32 op, void *data)
{
#if DEBUG
printf("IPCP: StackControl(op=%ld)\n", op);
#endif
// TODO:
// check values
switch(op) {
case SIOCSIFADDR:
break;
case SIOCSIFFLAGS:
break;
case SIOCSIFDSTADDR:
break;
case SIOCSIFNETMASK:
break;
default:
printf("IPCP: Unknown ioctl: %ld\n", op);
return PPPProtocol::StackControl(op, data);
}
return B_OK;
}
bool
IPCP::Up()
{
@ -149,12 +180,12 @@ IPCP::Down()
status_t
IPCP::Send(struct mbuf *packet, uint16 protocolNumber = IPCP_PROTOCOL)
{
if(protocolNumber != IPCP_PROTOCOL && protocolNumber != IP_PROTOCOL) {
m_freem(packet);
return B_ERROR;
}
if((protocolNumber == IP_PROTOCOL && State() == PPP_OPENED_STATE)
|| protocolNumber == IPCP_PROTOCOL)
return SendToNext(packet, protocolNumber);
return SendToNext(packet, protocolNumber);
m_freem(packet);
return B_ERROR;
}
@ -183,7 +214,6 @@ IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
if(ntohs(data->length) < 4)
return B_ERROR;
// packet is freed by event methods
switch(data->code) {
case PPP_CONFIGURE_REQUEST:
@ -224,7 +254,7 @@ IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
status_t
IPCP::ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber)
{
if(protocolNumber != IP_PROTOCOL)
if(protocolNumber != IP_PROTOCOL || State() != PPP_OPENED_STATE)
return PPP_UNHANDLED;
if(!packet)
@ -232,8 +262,8 @@ IPCP::ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber)
// TODO: add VJC support (the packet would be decoded here)
if (proto[IPPROTO_IP] && proto[IPPROTO_IP]->pr_input) {
proto[IPPROTO_IP]->pr_input(packet, 0);
if (gProto[IPPROTO_IP] && gProto[IPPROTO_IP]->pr_input) {
gProto[IPPROTO_IP]->pr_input(packet, 0);
return B_OK;
} else {
printf("IPCP: Error: Could not find input function for IP!\n");
@ -333,19 +363,53 @@ IPCP::UpdateAddresses()
if(!Interface().IsUp() && !Interface().DoesDialOnDemand())
return;
struct sockaddr_in *address;
struct ifreq ifreq;
memset(&ifreq, 0, sizeof(ifreq));
in_addr_t netmask;
struct in_aliasreq inreq;
struct ifreq ifreqAddress, ifreqDestination;
address = (struct sockaddr_in*) &ifreq.ifr_addr;
address->sin_family = AF_INET;
address->sin_addr.s_addr = fLocalConfiguration.address;
in_control(NULL, SIOCSIFADDR, (caddr_t) &ifreq, Interface().Ifnet());
inreq.ifra_addr.sin_family = AF_INET;
if(fLocalRequests.address != INADDR_ANY)
inreq.ifra_addr.sin_addr.s_addr = fLocalRequests.address;
else if(fLocalConfiguration.address == INADDR_ANY)
inreq.ifra_addr.sin_addr.s_addr = INADDR_BROADCAST;
else
inreq.ifra_addr.sin_addr.s_addr = fLocalConfiguration.address;
inreq.ifra_addr.sin_len = sizeof(sockaddr_in);
memcpy(&ifreqAddress.ifr_addr, &inreq.ifra_addr, sizeof(sockaddr_in));
address = (struct sockaddr_in*) &ifreq.ifr_dstaddr;
address->sin_family = AF_INET;
address->sin_addr.s_addr = fPeerConfiguration.address;
in_control(NULL, SIOCSIFDSTADDR, (caddr_t) &ifreq, Interface().Ifnet());
inreq.ifra_dstaddr.sin_family = AF_INET;
if(fPeerRequests.address != INADDR_ANY)
inreq.ifra_dstaddr.sin_addr.s_addr = fPeerRequests.address;
else if(fPeerConfiguration.address == INADDR_ANY)
inreq.ifra_dstaddr.sin_addr.s_addr = INADDR_BROADCAST;
else
inreq.ifra_dstaddr.sin_addr.s_addr = fPeerConfiguration.address;
inreq.ifra_dstaddr.sin_len = sizeof(sockaddr_in);
memcpy(&ifreqDestination.ifr_dstaddr, &inreq.ifra_dstaddr, sizeof(sockaddr_in));
inreq.ifra_mask.sin_family = AF_INET;
if(fLocalRequests.netmask != INADDR_ANY)
netmask = fLocalRequests.netmask;
else if(State() != PPP_OPENED_STATE)
netmask = INADDR_BROADCAST;
else if(IN_CLASSA(fLocalConfiguration.address))
netmask = IN_CLASSA_NET;
else if(IN_CLASSB(fLocalConfiguration.address))
netmask = IN_CLASSB_NET;
else
netmask = IN_CLASSC_NET;
inreq.ifra_mask.sin_addr.s_addr = netmask;
inreq.ifra_mask.sin_len = sizeof(sockaddr_in);
if(in_control(NULL, SIOCSIFADDR, (caddr_t) &ifreqAddress,
Interface().Ifnet()) != B_OK)
printf("IPCP: UpdateAddress(): SIOCSIFADDR returned error!\n");
if(in_control(NULL, SIOCSIFDSTADDR, (caddr_t) &ifreqDestination,
Interface().Ifnet()) != B_OK)
printf("IPCP: UpdateAddress(): SIOCSIFDSTADDR returned error!\n");
if(in_control(NULL, SIOCSIFNETMASK, (caddr_t) &inreq.ifra_mask,
Interface().Ifnet()) != B_OK)
printf("IPCP: UpdateAddress(): SIOCSIFNETMASK returned error!\n");
}
@ -490,7 +554,8 @@ IPCP::RCREvent(struct mbuf *packet)
if(item->length != 6) {
// the packet is invalid
m_freem(packet);
Down();
NewState(PPP_INITIAL_STATE);
ReportUpFailedEvent();
return;
}
@ -499,7 +564,8 @@ IPCP::RCREvent(struct mbuf *packet)
if(*requestedAddress == INADDR_ANY) {
// we do not have an address for you
m_freem(packet);
Down();
NewState(PPP_INITIAL_STATE);
ReportUpFailedEvent();
return;
}
} else if(*requestedAddress != *wishedAddress) {
@ -828,7 +894,8 @@ IPCP::RCNEvent(struct mbuf *packet)
default:
// DNS and addresses must be supported if we set them to auto
m_freem(packet);
Down();
NewState(PPP_INITIAL_STATE);
ReportUpFailedEvent();
return;
}
}
@ -1085,9 +1152,18 @@ IPCP::SendConfigureRequest()
// add address
ipItem.type = IPCP_ADDRESS;
ipItem.address = fLocalRequests.address;
if(fLocalRequests.address == INADDR_ANY)
ipItem.address = fLocalConfiguration.address;
else
ipItem.address = fLocalRequests.address;
request.AddItem((ppp_configure_item*) &ipItem);
#if DEBUG
printf("IPCP: SCR: confaddr=%lX; reqaddr=%lX; addr=%lX\n",
fLocalConfiguration.address, fLocalRequests.address,
((ip_item*)request.ItemAt(0))->address);
#endif
// add primary DNS (if needed)
if(fRequestPrimaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) {
ipItem.type = IPCP_PRIMARY_DNS;

View File

@ -23,7 +23,7 @@
typedef struct ip_item {
uint8 type;
uint8 length;
in_addr_t address;
in_addr_t address _PACKED;
} ip_item;
@ -54,7 +54,7 @@ typedef struct ipcp_configuration {
} ipcp_configuration;
extern struct protosw *proto[];
extern struct protosw *gProto[];
// defined in ipcp.cpp
@ -66,6 +66,8 @@ class IPCP : public PPPProtocol {
ppp_state State() const
{ return fState; }
virtual status_t StackControl(uint32 op, void *data);
virtual bool Up();
virtual bool Down();

View File

@ -26,12 +26,10 @@
#define IPCP_MODULE_NAME "network/ppp/ipcp"
struct protosw *proto[IPPROTO_MAX];
struct protosw *gProto[IPPROTO_MAX];
struct core_module_info *core = NULL;
status_t std_ops(int32 op, ...);
static BLocker lock;
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// TODO: Remove isascii() (needed for inet_aton()) when our kernel is finished!
@ -91,8 +89,8 @@ std_ops(int32 op, ...)
case B_MODULE_INIT:
if(get_module(NET_CORE_MODULE_NAME, (module_info**) &core) != B_OK)
return B_ERROR;
memset(proto, 0, sizeof(struct protosw*) * IPPROTO_MAX);
add_protosw(proto, NET_LAYER1);
memset(gProto, 0, sizeof(struct protosw*) * IPPROTO_MAX);
add_protosw(gProto, NET_LAYER1);
return B_OK;
case B_MODULE_UNINIT:

View File

@ -36,7 +36,7 @@
typedef struct authentication_item {
uint8 type;
uint8 length;
uint16 protocolNumber;
uint16 protocolNumber _PACKED;
} authentication_item;
@ -120,7 +120,7 @@ PAPHandler::Reset()
// PAP
PAP::PAP(PPPInterface& interface, driver_parameter *settings)
: PPPProtocol("PAP", PPP_AUTHENTICATION_PHASE, PAP_PROTOCOL, PPP_PROTOCOL_LEVEL,
AF_INET, 0, interface, settings, PPP_NO_FLAGS,
AF_INET, 0, interface, settings, PPP_ALWAYS_ALLOWED,
AUTHENTICATOR_TYPE_STRING, new PAPHandler(*this, interface)),
fState(INITIAL),
fID(system_time() & 0xFF),
@ -404,6 +404,11 @@ PAP::TOBadEvent()
case WAITING_FOR_REQ:
NewState(INITIAL);
locker.UnlockNow();
if(State() == REQ_SENT)
Interface().StateMachine().LocalAuthenticationDenied(fUser);
else
Interface().StateMachine().PeerAuthenticationDenied(fUser);
UpFailedEvent();
break;
@ -556,7 +561,7 @@ PAP::SendRequest()
data[0] = strlen(fUser);
memcpy(data + 1, fUser, strlen(fUser));
data[1 + data[0]] = strlen(fPassword);
memcpy(data + 2 + data[0], fUser, strlen(fUser));
memcpy(data + 2 + data[0], fPassword, strlen(fPassword));
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
}

View File

@ -49,7 +49,7 @@ add_to(PPPInterface& mainInterface, PPPInterface *subInterface,
}
#if DEBUG
printf("IPCP: add_to(): %s\n",
printf("PAP: add_to(): %s\n",
success && pap && pap->InitCheck() == B_OK ? "OK" : "ERROR");
#endif

View File

@ -24,7 +24,7 @@
#if DEBUG
static char digits[] = "0123456789ABCDEF";
static char sDigits[] = "0123456789ABCDEF";
void
dump_packet(struct mbuf *packet)
{
@ -39,8 +39,8 @@ dump_packet(struct mbuf *packet)
packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : -1);
for(uint32 index = 0; index < packet->m_len; index++) {
buffer[bufferIndex++] = digits[data[index] >> 4];
buffer[bufferIndex++] = digits[data[index] & 0x0F];
buffer[bufferIndex++] = sDigits[data[index] >> 4];
buffer[bufferIndex++] = sDigits[data[index] & 0x0F];
if(bufferIndex == 32 || index == packet->m_len - 1) {
buffer[bufferIndex] = 0;
printf("%s\n", buffer);

View File

@ -30,18 +30,18 @@
#define PPPoE_MODULE_NAME "network/ppp/pppoe"
struct core_module_info *core = NULL;
static struct ethernet_module_info *ethernet;
static int32 host_uniq = 0;
static struct ethernet_module_info *sEthernet;
static int32 sHostUniq = 0;
status_t std_ops(int32 op, ...);
static BLocker lock;
static List<PPPoEDevice*> *devices;
static BLocker sLock;
static List<PPPoEDevice*> *sDevices;
uint32
NewHostUniq()
{
return (uint32) atomic_add(&host_uniq, 1);
return (uint32) atomic_add(&sHostUniq, 1);
}
@ -52,8 +52,8 @@ add_device(PPPoEDevice *device)
printf("PPPoE: add_device()\n");
#endif
LockerHelper locker(lock);
devices->AddItem(device);
LockerHelper locker(sLock);
sDevices->AddItem(device);
}
@ -64,8 +64,8 @@ remove_device(PPPoEDevice *device)
printf("PPPoE: remove_device()\n");
#endif
LockerHelper locker(lock);
devices->RemoveItem(device);
LockerHelper locker(sLock);
sDevices->RemoveItem(device);
}
@ -76,18 +76,14 @@ pppoe_input(struct mbuf *packet)
if(!packet)
return;
#if DEBUG
// dump_packet(packet);
#endif
ifnet *sourceIfnet = packet->m_pkthdr.rcvif;
complete_pppoe_header *header = mtod(packet, complete_pppoe_header*);
PPPoEDevice *device;
LockerHelper locker(lock);
LockerHelper locker(sLock);
for(int32 index = 0; index < devices->CountItems(); index++) {
device = devices->ItemAt(index);
for(int32 index = 0; index < sDevices->CountItems(); index++) {
device = sDevices->ItemAt(index);
if(device && device->EthernetIfnet() == sourceIfnet) {
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE
@ -173,14 +169,14 @@ std_ops(int32 op, ...)
return B_ERROR;
if(get_module(NET_ETHERNET_MODULE_NAME,
(module_info**) &ethernet) != B_OK) {
(module_info**) &sEthernet) != B_OK) {
put_module(NET_CORE_MODULE_NAME);
return B_ERROR;
}
devices = new List<PPPoEDevice*>;
sDevices = new List<PPPoEDevice*>;
ethernet->set_pppoe_receiver(pppoe_input);
sEthernet->set_pppoe_receiver(pppoe_input);
#if DEBUG
printf("PPPoE: Registered PPPoE receiver.\n");
@ -188,8 +184,8 @@ std_ops(int32 op, ...)
return B_OK;
case B_MODULE_UNINIT:
delete devices;
ethernet->unset_pppoe_receiver();
delete sDevices;
sEthernet->unset_pppoe_receiver();
#if DEBUG
printf("PPPoE: Unregistered PPPoE receiver.\n");
#endif

View File

@ -62,8 +62,8 @@ 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 *parent = NULL)
PPPInterface::PPPInterface(ppp_interface_entry *entry, uint32 ID,
const driver_settings *settings, PPPInterface *parent = NULL)
: PPPLayer("PPPInterface", PPP_INTERFACE_LEVEL, 2),
fID(ID),
fSettings(dup_driver_settings(settings)),
@ -95,6 +95,8 @@ PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
fLock(StateMachine().fLock),
fDeleteCounter(0)
{
entry->interface = this;
// add internal modules
// LCP
if(!AddProtocol(&LCP())) {
@ -518,7 +520,8 @@ PPPInterface::AddProtocol(PPPProtocol *protocol)
// with the same level.
#if DEBUG
printf("PPPInterface: AddProtocol()\n");
printf("PPPInterface: AddProtocol(%X)\n",
protocol ? protocol->ProtocolNumber() : 0);
#endif
if(!protocol || &protocol->Interface() != this
@ -575,7 +578,8 @@ bool
PPPInterface::RemoveProtocol(PPPProtocol *protocol)
{
#if DEBUG
printf("PPPInterface: RemoveProtocol()\n");
printf("PPPInterface: RemoveProtocol(%X)\n",
protocol ? protocol->ProtocolNumber() : 0);
#endif
LockerHelper locker(fLock);
@ -661,7 +665,8 @@ bool
PPPInterface::AddChild(PPPInterface *child)
{
#if DEBUG
printf("PPPInterface: AddChild()\n");
printf("PPPInterface: AddChild(%lX)\n",
child ? child->ID() : 0);
#endif
if(!child)
@ -682,7 +687,8 @@ bool
PPPInterface::RemoveChild(PPPInterface *child)
{
#if DEBUG
printf("PPPInterface: RemoveChild()\n");
printf("PPPInterface: RemoveChild(%lX)\n",
child ? child->ID() : 0);
#endif
LockerHelper locker(fLock);
@ -1014,6 +1020,7 @@ PPPInterface::Down()
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);
@ -1307,11 +1314,12 @@ PPPInterface::ReceiveFromDevice(struct mbuf *packet)
// decode ppp frame and recognize PFC
uint16 protocolNumber = *mtod(packet, uint8*);
if(protocolNumber == 0)
m_adj(packet, 1);
else {
if(protocolNumber & 0x80 || protocolNumber == 0) {
protocolNumber = ntohs(*mtod(packet, uint16*));
m_adj(packet, 2);
} else {
m_adj(packet, 1);
protocolNumber = *mtod(packet, uint8*);
}
return Receive(packet, protocolNumber);

View File

@ -88,8 +88,8 @@ bool
PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 length)
{
#if DEBUG
printf("PPPReportManager: Report(type=%d code=%ld length=%ld)\n",
type, code, length);
printf("PPPReportManager: Report(type=%d code=%ld length=%ld) to %ld receivers\n",
type, code, length, fReportRequests.CountItems());
#endif
if(length > PPP_REPORT_DATA_LIMIT)

View File

@ -102,9 +102,6 @@ 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()) {
if(!Interface().DoesDialOnDemand())
Interface().UnregisterInterface();
if(Interface().Ifnet()) {
Interface().Ifnet()->if_flags &= ~IFF_RUNNING;
@ -1980,6 +1977,7 @@ PPPStateMachine::BringProtocolsUp()
else if(Phase() == PPP_ESTABLISHED_PHASE) {
if(Interface().Parent())
Interface().Parent()->StateMachine().UpEvent(Interface());
break;
} else
NewPhase((ppp_phase) (Phase() + 1));
}

View File

@ -13,13 +13,22 @@
#include <netinet/in.h>
#ifdef _KERNEL_MODE
#include <KernelExport.h>
#define spawn_thread spawn_kernel_thread
#define printf dprintf
#elif DEBUG
#include <cstdio>
#endif
#define AUTHENTICATION_TYPE 0x3
#define AUTHENTICATOR_TYPE_STRING "Authenticator"
typedef struct authentication_item {
uint8 type;
uint8 length;
uint16 protocolNumber;
uint16 protocolNumber _PACKED;
} authentication_item;
@ -99,6 +108,10 @@ _PPPAuthenticationHandler::AddToRequest(PPPConfigurePacket& request)
// this could omit some authenticators when we get a suggestion, but that is
// no problem because the suggested authenticator will be accepted (hopefully)
#if DEBUG
printf("PPPAuthHandler: AddToRequest(%X)\n", authenticator->ProtocolNumber());
#endif
authenticator->SetEnabled(true);
return authenticator->OptionHandler()->AddToRequest(request);
// let protocol add its request
@ -189,6 +202,10 @@ _PPPAuthenticationHandler::ParseRequest(const PPPConfigurePacket& request,
return B_OK;
// no authentication requested by peer (index > request.CountItems())
#if DEBUG
printf("PPPAuthHandler: ParseRequest(%X)\n", ntohs(item->protocolNumber));
#endif
// try to find the requested protocol
fLocalAuthenticator = Interface().ProtocolFor(ntohs(item->protocolNumber));
if(fLocalAuthenticator &&

View File

@ -18,7 +18,7 @@
typedef struct mru_item {
uint8 type;
uint8 length;
uint16 MRU;
uint16 MRU _PACKED;
} mru_item;
status_t ParseRequestedItem(mru_item *item, PPPInterface& interface);

View File

@ -31,6 +31,7 @@ class PPPOptionHandler;
struct ppp_interface_module_info;
struct ppp_module_info;
struct ppp_interface_entry;
class PPPInterface : public PPPLayer {
@ -44,8 +45,8 @@ class PPPInterface : public PPPLayer {
PPPInterface& operator= (const PPPInterface& copy);
// only PPPManager may construct us!
PPPInterface(interface_id ID, const driver_settings *settings,
PPPInterface *parent = NULL);
PPPInterface(ppp_interface_entry *entry, interface_id ID,
const driver_settings *settings, PPPInterface *parent = NULL);
~PPPInterface();
public:

View File

@ -19,15 +19,23 @@
// create_interface() returns this value on failure
class PPPInterface;
typedef struct ppp_interface_entry {
PPPInterface *interface;
vint32 accessing;
bool deleting;
} ppp_interface_entry;
typedef struct ppp_interface_module_info {
kernel_net_module_info knminfo;
interface_id (*CreateInterface)(const driver_settings *settings,
interface_id parentID = PPP_UNDEFINED_INTERFACE_ID);
// you should always create interfaces using this function
void (*DeleteInterface)(interface_id ID);
bool (*DeleteInterface)(interface_id ID);
// this marks the interface for deletion
void (*RemoveInterface)(interface_id ID);
bool (*RemoveInterface)(interface_id ID);
// remove the interface from database (make sure you can delete it yourself!)
ifnet *(*RegisterInterface)(interface_id ID);

View File

@ -22,6 +22,7 @@ class PPPProtocol;
class PPPStateMachine {
friend class PPPInterface;
friend class PPPLCP;
friend class PPPManager;
private:
// may only be constructed/destructed by PPPInterface

View File

@ -15,7 +15,7 @@
static void copy_parameter(const driver_parameter *from, driver_parameter *to);
static void free_driver_parameter(driver_parameter *p);
static void free_driver_parameter(driver_parameter *parameter);
driver_settings*
@ -85,19 +85,19 @@ free_driver_settings(driver_settings *settings)
static
void
free_driver_parameter(driver_parameter *p)
free_driver_parameter(driver_parameter *parameter)
{
free(p->name);
free(parameter->name);
for(int32 index = 0; index < p->value_count; index++)
free(p->values[index]);
for(int32 index = 0; index < parameter->value_count; index++)
free(parameter->values[index]);
free(p->values);
free(parameter->values);
for(int32 index = 0; index < p->parameter_count; index++)
free_driver_parameter(&p->parameters[index]);
for(int32 index = 0; index < parameter->parameter_count; index++)
free_driver_parameter(&parameter->parameters[index]);
free(p->parameters);
free(parameter->parameters);
}