Fixed many bugs and added debug output.
You can now successfully (dis-)connect to(/from) a PPP server using the PPPoE device module. To be useful we need the PAP and IPCP modules (in the works). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5276 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -51,6 +51,7 @@ bring_interface_up(interface_entry *entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if DOWN_AS_THREAD
|
||||||
static
|
static
|
||||||
status_t
|
status_t
|
||||||
interface_down_thread(void *data)
|
interface_down_thread(void *data)
|
||||||
@@ -62,15 +63,21 @@ interface_down_thread(void *data)
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
status_t
|
status_t
|
||||||
bring_interface_down(interface_entry *entry)
|
bring_interface_down(interface_entry *entry)
|
||||||
{
|
{
|
||||||
|
#if DOWN_AS_THREAD
|
||||||
thread_id downThread = spawn_thread(interface_down_thread,
|
thread_id downThread = spawn_thread(interface_down_thread,
|
||||||
"PPPManager: down_thread", B_NORMAL_PRIORITY, entry);
|
"PPPManager: down_thread", B_NORMAL_PRIORITY, entry);
|
||||||
resume_thread(downThread);
|
resume_thread(downThread); */
|
||||||
|
#else
|
||||||
|
entry->interface->Down();
|
||||||
|
--entry->accessing;
|
||||||
|
#endif
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -219,6 +226,7 @@ PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
|
|||||||
if(!entry || entry->deleting)
|
if(!entry || entry->deleting)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
int32 status = B_OK;
|
||||||
++entry->accessing;
|
++entry->accessing;
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
|
|
||||||
@@ -235,11 +243,11 @@ PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return entry->interface->StackControl(cmd, data);
|
status = entry->interface->StackControl(cmd, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
--entry->accessing;
|
--entry->accessing;
|
||||||
return B_OK;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -300,6 +308,7 @@ PPPManager::DeleteInterface(interface_id ID)
|
|||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
interface_entry *entry = EntryFor(ID);
|
interface_entry *entry = EntryFor(ID);
|
||||||
|
entry->interface->Down();
|
||||||
if(entry)
|
if(entry)
|
||||||
entry->deleting = true;
|
entry->deleting = true;
|
||||||
}
|
}
|
||||||
@@ -430,9 +439,11 @@ PPPManager::Control(uint32 op, void *data, size_t length)
|
|||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
interface_entry *entry = EntryFor(*(interface_id*)data);
|
interface_entry *entry = EntryFor(*(interface_id*)data);
|
||||||
if(!entry)
|
if(!entry || entry->deleting)
|
||||||
return B_BAD_INDEX;
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
|
++entry->accessing;
|
||||||
|
|
||||||
return bring_interface_up(entry);
|
return bring_interface_up(entry);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -443,9 +454,11 @@ PPPManager::Control(uint32 op, void *data, size_t length)
|
|||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
interface_entry *entry = EntryFor(*(interface_id*)data);
|
interface_entry *entry = EntryFor(*(interface_id*)data);
|
||||||
if(!entry)
|
if(!entry || entry->deleting)
|
||||||
return B_BAD_INDEX;
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
|
++entry->accessing;
|
||||||
|
|
||||||
return bring_interface_down(entry);
|
return bring_interface_down(entry);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -457,7 +470,7 @@ PPPManager::Control(uint32 op, void *data, size_t length)
|
|||||||
|
|
||||||
ppp_control_info *control = (ppp_control_info*) data;
|
ppp_control_info *control = (ppp_control_info*) data;
|
||||||
interface_entry *entry = EntryFor(control->index);
|
interface_entry *entry = EntryFor(control->index);
|
||||||
if(!entry)
|
if(!entry || entry->deleting)
|
||||||
return B_BAD_INDEX;
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
return entry->interface->Control(control->op, control->data,
|
return entry->interface->Control(control->op, control->data,
|
||||||
@@ -711,7 +724,7 @@ PPPManager::DeleterThreadEvent()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entry->deleting && entry->accessing == 0) {
|
if(entry->deleting && entry->accessing <= 0) {
|
||||||
delete entry->interface;
|
delete entry->interface;
|
||||||
delete entry;
|
delete entry;
|
||||||
fEntries.RemoveItem(index);
|
fEntries.RemoveItem(index);
|
||||||
|
|||||||
@@ -76,8 +76,7 @@ class PPPManager {
|
|||||||
PPPReportManager fReportManager;
|
PPPReportManager fReportManager;
|
||||||
List<interface_entry*> fEntries;
|
List<interface_entry*> fEntries;
|
||||||
interface_id fNextID, fRegisterRequestor;
|
interface_id fNextID, fRegisterRequestor;
|
||||||
thread_id fDeleterThread;
|
thread_id fDeleterThread, fPulseTimer;
|
||||||
net_timer_id fPulseTimer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,31 +12,40 @@
|
|||||||
|
|
||||||
DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000)
|
DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000)
|
||||||
: fCode(code),
|
: fCode(code),
|
||||||
fSessionID(sessionID)
|
fSessionID(sessionID),
|
||||||
|
fInitStatus(B_OK)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DiscoveryPacket::DiscoveryPacket(struct mbuf *packet)
|
DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start = 0)
|
||||||
{
|
{
|
||||||
// decode packet
|
// decode packet
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
uint8 *data = mtod(packet, uint8*);
|
||||||
|
data += start;
|
||||||
|
pppoe_header *header = (pppoe_header*) data;
|
||||||
|
|
||||||
SetCode(header->code);
|
SetCode(header->code);
|
||||||
|
|
||||||
if(ntohs(header->length) < 4)
|
uint16 length = ntohs(header->length);
|
||||||
|
|
||||||
|
if(length > packet->m_len - PPPoE_HEADER_SIZE - start) {
|
||||||
|
fInitStatus = B_ERROR;
|
||||||
return;
|
return;
|
||||||
// there are no tags (or one corrupted tag)
|
// there are no tags (or one corrupted tag)
|
||||||
|
}
|
||||||
|
|
||||||
int32 position = 0;
|
int32 position = 0;
|
||||||
pppoe_tag *tag;
|
pppoe_tag *tag;
|
||||||
|
|
||||||
while(position <= ntohs(header->length) - 4) {
|
while(position <= length - 4) {
|
||||||
tag = (pppoe_tag*) (header->data + position);
|
tag = (pppoe_tag*) (header->data + position);
|
||||||
position += ntohs(tag->length) + 4;
|
position += ntohs(tag->length) + 4;
|
||||||
|
|
||||||
AddTag(ntohs(tag->type), ntohs(tag->length), tag->data);
|
AddTag(ntohs(tag->type), ntohs(tag->length), tag->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fInitStatus = B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -110,15 +119,13 @@ DiscoveryPacket::TagWithType(uint16 type) const
|
|||||||
|
|
||||||
|
|
||||||
struct mbuf*
|
struct mbuf*
|
||||||
DiscoveryPacket::ToMbuf(uint32 reserve = 0)
|
DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve = ETHER_HDR_LEN)
|
||||||
{
|
{
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||||
packet->m_data += reserve;
|
packet->m_data += reserve;
|
||||||
|
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||||
|
|
||||||
memset(header, 0, sizeof(header));
|
|
||||||
header->ethernetHeader.ether_type = ETHERTYPE_PPPOEDISC;
|
|
||||||
header->version = PPPoE_VERSION;
|
header->version = PPPoE_VERSION;
|
||||||
header->type = PPPoE_TYPE;
|
header->type = PPPoE_TYPE;
|
||||||
header->code = Code();
|
header->code = Code();
|
||||||
@@ -131,7 +138,7 @@ DiscoveryPacket::ToMbuf(uint32 reserve = 0)
|
|||||||
tag = TagAt(index);
|
tag = TagAt(index);
|
||||||
|
|
||||||
// make sure we have enough space left
|
// make sure we have enough space left
|
||||||
if(1494 - length < tag->length) {
|
if(MTU - length < tag->length) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -145,7 +152,7 @@ DiscoveryPacket::ToMbuf(uint32 reserve = 0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
header->length = htons(length);
|
header->length = htons(length);
|
||||||
packet->m_len = length;
|
packet->m_pkthdr.len = packet->m_len = length + PPPoE_HEADER_SIZE;
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,12 @@ typedef struct pppoe_tag {
|
|||||||
class DiscoveryPacket {
|
class DiscoveryPacket {
|
||||||
public:
|
public:
|
||||||
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
|
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
|
||||||
DiscoveryPacket(struct mbuf *packet);
|
DiscoveryPacket(struct mbuf *packet, uint32 start = 0);
|
||||||
~DiscoveryPacket();
|
~DiscoveryPacket();
|
||||||
|
|
||||||
|
status_t InitCheck() const
|
||||||
|
{ return fInitStatus; }
|
||||||
|
|
||||||
void SetCode(uint8 code)
|
void SetCode(uint8 code)
|
||||||
{ fCode = code; }
|
{ fCode = code; }
|
||||||
uint8 Code() const
|
uint8 Code() const
|
||||||
@@ -65,13 +68,14 @@ class DiscoveryPacket {
|
|||||||
pppoe_tag *TagAt(int32 index) const;
|
pppoe_tag *TagAt(int32 index) const;
|
||||||
pppoe_tag *TagWithType(uint16 type) const;
|
pppoe_tag *TagWithType(uint16 type) const;
|
||||||
|
|
||||||
struct mbuf *ToMbuf(uint32 reserve = 0);
|
struct mbuf *ToMbuf(uint32 MTU, uint32 reserve = ETHER_HDR_LEN);
|
||||||
// the user is responsible for freeing the mbuf
|
// the user is responsible for freeing the mbuf
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 fCode;
|
uint8 fCode;
|
||||||
uint16 fSessionID;
|
uint16 fSessionID;
|
||||||
List<pppoe_tag*> fTags;
|
List<pppoe_tag*> fTags;
|
||||||
|
status_t fInitStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,14 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/if_ether.h>
|
#include <netinet/if_ether.h>
|
||||||
|
|
||||||
|
class PPPoEDevice;
|
||||||
|
|
||||||
#define PPPoE_HEADER_SIZE 14
|
|
||||||
// including ethernet header
|
#define PPPoE_HEADER_SIZE 6
|
||||||
|
// without ethernet header
|
||||||
#define PPPoE_TIMEOUT 3000000
|
#define PPPoE_TIMEOUT 3000000
|
||||||
// 3 seconds
|
// 3 seconds
|
||||||
|
#define PPPoE_MAX_ATTEMPTS 2
|
||||||
|
|
||||||
#define PPPoE_VERSION 0x1
|
#define PPPoE_VERSION 0x1
|
||||||
#define PPPoE_TYPE 0x1
|
#define PPPoE_TYPE 0x1
|
||||||
@@ -27,7 +30,6 @@ extern struct core_module_info *core;
|
|||||||
|
|
||||||
|
|
||||||
typedef struct pppoe_header {
|
typedef struct pppoe_header {
|
||||||
struct ether_header ethernetHeader;
|
|
||||||
uint8 version : 4;
|
uint8 version : 4;
|
||||||
uint8 type : 4;
|
uint8 type : 4;
|
||||||
uint8 code;
|
uint8 code;
|
||||||
@@ -36,9 +38,19 @@ typedef struct pppoe_header {
|
|||||||
uint8 data[0];
|
uint8 data[0];
|
||||||
} pppoe_header _PACKED;
|
} pppoe_header _PACKED;
|
||||||
|
|
||||||
|
typedef struct complete_pppoe_header {
|
||||||
|
struct ether_header ethernetHeader;
|
||||||
|
pppoe_header pppoeHeader;
|
||||||
|
} complete_pppoe_header;
|
||||||
|
|
||||||
|
|
||||||
uint32 NewHostUniq();
|
|
||||||
// defined in pppoe.cpp
|
// defined in pppoe.cpp
|
||||||
|
uint32 NewHostUniq();
|
||||||
|
void add_device(PPPoEDevice *device);
|
||||||
|
void remove_device(PPPoEDevice *device);
|
||||||
|
|
||||||
|
// defined in PPPoEDevice.cpp
|
||||||
|
void dump_packet(struct mbuf *packet);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,13 +23,42 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
static char digits[] = "0123456789ABCDEF";
|
||||||
|
void
|
||||||
|
dump_packet(struct mbuf *packet)
|
||||||
|
{
|
||||||
|
if(!packet)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint8 *data = mtod(packet, uint8*);
|
||||||
|
uint8 buffer[33];
|
||||||
|
uint8 bufferIndex = 0;
|
||||||
|
|
||||||
|
printf("Dumping packet;len=%ld;pkthdr.len=%d\n", packet->m_len,
|
||||||
|
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];
|
||||||
|
if(bufferIndex == 32 || index == packet->m_len - 1) {
|
||||||
|
buffer[bufferIndex] = 0;
|
||||||
|
printf("%s\n", buffer);
|
||||||
|
bufferIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PPPoEDevice::PPPoEDevice(PPPInterface& interface, driver_parameter *settings)
|
PPPoEDevice::PPPoEDevice(PPPInterface& interface, driver_parameter *settings)
|
||||||
: PPPDevice("PPPoE", interface, settings),
|
: PPPDevice("PPPoE", PPPoE_HEADER_SIZE + ETHER_HDR_LEN, interface, settings),
|
||||||
fEthernetIfnet(NULL),
|
fEthernetIfnet(NULL),
|
||||||
fSessionID(0),
|
fSessionID(0),
|
||||||
fHostUniq(NewHostUniq()),
|
fHostUniq(NewHostUniq()),
|
||||||
fACName(NULL),
|
fACName(NULL),
|
||||||
fServiceName(NULL),
|
fServiceName(NULL),
|
||||||
|
fAttempts(0),
|
||||||
fNextTimeout(0),
|
fNextTimeout(0),
|
||||||
fState(INITIAL)
|
fState(INITIAL)
|
||||||
{
|
{
|
||||||
@@ -67,6 +96,8 @@ PPPoEDevice::PPPoEDevice(PPPInterface& interface, driver_parameter *settings)
|
|||||||
if(!fEthernetIfnet)
|
if(!fEthernetIfnet)
|
||||||
printf("PPPoEDevice::ctor: could not find ethernet interface\n");
|
printf("PPPoEDevice::ctor: could not find ethernet interface\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
add_device(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -76,6 +107,8 @@ PPPoEDevice::~PPPoEDevice()
|
|||||||
printf("PPPoEDevice: Destructor\n");
|
printf("PPPoEDevice: Destructor\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
remove_device(this);
|
||||||
|
|
||||||
free(fACName);
|
free(fACName);
|
||||||
free(fServiceName);
|
free(fServiceName);
|
||||||
}
|
}
|
||||||
@@ -104,6 +137,15 @@ PPPoEDevice::Up()
|
|||||||
if(IsUp())
|
if(IsUp())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
fState = INITIAL;
|
||||||
|
// reset state
|
||||||
|
|
||||||
|
if(fAttempts > PPPoE_MAX_ATTEMPTS) {
|
||||||
|
fAttempts = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
++fAttempts;
|
||||||
// reset connection settings
|
// reset connection settings
|
||||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||||
|
|
||||||
@@ -113,33 +155,41 @@ PPPoEDevice::Up()
|
|||||||
discovery.AddTag(SERVICE_NAME, strlen(fServiceName), fServiceName);
|
discovery.AddTag(SERVICE_NAME, strlen(fServiceName), fServiceName);
|
||||||
else
|
else
|
||||||
discovery.AddTag(SERVICE_NAME, 0, NULL);
|
discovery.AddTag(SERVICE_NAME, 0, NULL);
|
||||||
discovery.AddTag(HOST_UNIQ, sizeof(uint32), &fHostUniq);
|
discovery.AddTag(HOST_UNIQ, sizeof(fHostUniq), &fHostUniq);
|
||||||
discovery.AddTag(END_OF_LIST, 0, NULL);
|
discovery.AddTag(END_OF_LIST, 0, NULL);
|
||||||
|
|
||||||
// set up PPP header
|
// set up PPP header
|
||||||
struct mbuf *packet = discovery.ToMbuf();
|
struct mbuf *packet = discovery.ToMbuf(MTU());
|
||||||
if(!packet)
|
if(!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// create destination
|
// create destination
|
||||||
|
struct ether_header *ethernetHeader;
|
||||||
struct sockaddr destination;
|
struct sockaddr destination;
|
||||||
memset(&destination, 0, sizeof(destination));
|
memset(&destination, 0, sizeof(destination));
|
||||||
destination.sa_family = AF_UNSPEC;
|
destination.sa_family = AF_UNSPEC;
|
||||||
// raw packet with ethernet header
|
// raw packet with ethernet header
|
||||||
memcpy(destination.sa_data, fPeer, sizeof(fPeer));
|
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||||
|
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
||||||
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK)
|
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||||
return false;
|
|
||||||
|
|
||||||
// check if we are allowed to go up now (user intervention might disallow that)
|
// check if we are allowed to go up now (user intervention might disallow that)
|
||||||
if(!UpStarted()) {
|
if(fAttempts > 0 && !UpStarted()) {
|
||||||
fState = INITIAL;
|
fAttempts = 0;
|
||||||
// reset state
|
|
||||||
DownEvent();
|
DownEvent();
|
||||||
return true;
|
return true;
|
||||||
|
// there was no error
|
||||||
}
|
}
|
||||||
|
|
||||||
fState = PADI_SENT;
|
fState = PADI_SENT;
|
||||||
|
// needed before sending, otherwise we might not get all packets
|
||||||
|
|
||||||
|
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK) {
|
||||||
|
fState = INITIAL;
|
||||||
|
fAttempts = 0;
|
||||||
|
printf("PPPoEDevice::Up(): EthernetIfnet()->output() failed!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
||||||
|
|
||||||
@@ -159,33 +209,39 @@ PPPoEDevice::Down()
|
|||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
fState = INITIAL;
|
||||||
|
fAttempts = 0;
|
||||||
fNextTimeout = 0;
|
fNextTimeout = 0;
|
||||||
// disable timeouts
|
// disable timeouts
|
||||||
|
|
||||||
DownStarted();
|
|
||||||
// this tells StateMachine that DownEvent() does not mean we lost connection
|
|
||||||
|
|
||||||
if(!IsUp()) {
|
if(!IsUp()) {
|
||||||
DownEvent();
|
DownEvent();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DownStarted();
|
||||||
|
// this tells StateMachine that DownEvent() does not mean we lost connection
|
||||||
|
|
||||||
// create PADT
|
// create PADT
|
||||||
DiscoveryPacket discovery(PADT, SessionID());
|
DiscoveryPacket discovery(PADT, SessionID());
|
||||||
discovery.AddTag(END_OF_LIST, 0, NULL);
|
discovery.AddTag(END_OF_LIST, 0, NULL);
|
||||||
|
|
||||||
struct mbuf *packet = discovery.ToMbuf();
|
struct mbuf *packet = discovery.ToMbuf(MTU());
|
||||||
if(!packet) {
|
if(!packet) {
|
||||||
|
printf("PPPoEDevice::Down(): ToMbuf() failed; MTU=%ld\n", MTU());
|
||||||
DownEvent();
|
DownEvent();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create destination
|
// create destination
|
||||||
|
struct ether_header *ethernetHeader;
|
||||||
struct sockaddr destination;
|
struct sockaddr destination;
|
||||||
memset(&destination, 0, sizeof(destination));
|
memset(&destination, 0, sizeof(destination));
|
||||||
destination.sa_family = AF_UNSPEC;
|
destination.sa_family = AF_UNSPEC;
|
||||||
// raw packet with ethernet header
|
// raw packet with ethernet header
|
||||||
memcpy(destination.sa_data, fPeer, sizeof(fPeer));
|
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||||
|
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
||||||
|
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||||
|
|
||||||
// reset connection settings
|
// reset connection settings
|
||||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||||
@@ -225,6 +281,7 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber = 0)
|
|||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("PPPoEDevice: Send()\n");
|
printf("PPPoEDevice: Send()\n");
|
||||||
|
dump_packet(packet);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(InitCheck() != B_OK || protocolNumber != 0) {
|
if(InitCheck() != B_OK || protocolNumber != 0) {
|
||||||
@@ -243,7 +300,6 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber = 0)
|
|||||||
// encapsulate packet into pppoe header
|
// encapsulate packet into pppoe header
|
||||||
M_PREPEND(packet, PPPoE_HEADER_SIZE);
|
M_PREPEND(packet, PPPoE_HEADER_SIZE);
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||||
header->ethernetHeader.ether_type = ETHERTYPE_PPPOE;
|
|
||||||
header->version = PPPoE_VERSION;
|
header->version = PPPoE_VERSION;
|
||||||
header->type = PPPoE_TYPE;
|
header->type = PPPoE_TYPE;
|
||||||
header->code = 0x00;
|
header->code = 0x00;
|
||||||
@@ -251,11 +307,14 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber = 0)
|
|||||||
header->length = htons(length);
|
header->length = htons(length);
|
||||||
|
|
||||||
// create destination
|
// create destination
|
||||||
|
struct ether_header *ethernetHeader;
|
||||||
struct sockaddr destination;
|
struct sockaddr destination;
|
||||||
memset(&destination, 0, sizeof(destination));
|
memset(&destination, 0, sizeof(destination));
|
||||||
destination.sa_family = AF_UNSPEC;
|
destination.sa_family = AF_UNSPEC;
|
||||||
// raw packet with ethernet header
|
// raw packet with ethernet header
|
||||||
memcpy(destination.sa_data, fPeer, sizeof(fPeer));
|
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||||
|
ethernetHeader->ether_type = ETHERTYPE_PPPOE;
|
||||||
|
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||||
|
|
||||||
locker.UnlockNow();
|
locker.UnlockNow();
|
||||||
|
|
||||||
@@ -273,25 +332,26 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber = 0)
|
|||||||
status_t
|
status_t
|
||||||
PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0)
|
PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
printf("PPPoEDevice: Receive()\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(InitCheck() != B_OK || IsDown()) {
|
if(InitCheck() != B_OK || IsDown()) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
} else if(!packet)
|
} else if(!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
complete_pppoe_header *completeHeader = mtod(packet, complete_pppoe_header*);
|
||||||
if(!header) {
|
if(!completeHeader) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 ethernetSource[6];
|
||||||
|
memcpy(ethernetSource, completeHeader->ethernetHeader.ether_shost, sizeof(fPeer));
|
||||||
status_t result = B_OK;
|
status_t result = B_OK;
|
||||||
|
|
||||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE) {
|
if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOE) {
|
||||||
|
m_adj(packet, ETHER_HDR_LEN);
|
||||||
|
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||||
|
|
||||||
if(!IsUp() || header->version != PPPoE_VERSION || header->type != PPPoE_TYPE
|
if(!IsUp() || header->version != PPPoE_VERSION || header->type != PPPoE_TYPE
|
||||||
|| header->code != 0x0 || header->sessionID != SessionID()) {
|
|| header->code != 0x0 || header->sessionID != SessionID()) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
@@ -300,7 +360,10 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0)
|
|||||||
|
|
||||||
m_adj(packet, PPPoE_HEADER_SIZE);
|
m_adj(packet, PPPoE_HEADER_SIZE);
|
||||||
return Interface().ReceiveFromDevice(packet);
|
return Interface().ReceiveFromDevice(packet);
|
||||||
} else if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC) {
|
} else if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC) {
|
||||||
|
m_adj(packet, ETHER_HDR_LEN);
|
||||||
|
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||||
|
|
||||||
// we do not need to check HOST_UNIQ tag as this is done in pppoe.cpp
|
// we do not need to check HOST_UNIQ tag as this is done in pppoe.cpp
|
||||||
if(header->version != PPPoE_VERSION || header->type != PPPoE_TYPE) {
|
if(header->version != PPPoE_VERSION || header->type != PPPoE_TYPE) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
@@ -358,21 +421,27 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reply.AddTag(HOST_UNIQ, sizeof(fHostUniq), &fHostUniq);
|
||||||
reply.AddTag(END_OF_LIST, 0, NULL);
|
reply.AddTag(END_OF_LIST, 0, NULL);
|
||||||
struct mbuf *replyPacket = reply.ToMbuf();
|
struct mbuf *replyPacket = reply.ToMbuf(MTU());
|
||||||
if(!replyPacket) {
|
if(!replyPacket) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(fPeer, header->ethernetHeader.ether_shost, sizeof(fPeer));
|
memcpy(fPeer, ethernetSource, sizeof(fPeer));
|
||||||
|
|
||||||
// create destination
|
// create destination
|
||||||
|
struct ether_header *ethernetHeader;
|
||||||
struct sockaddr destination;
|
struct sockaddr destination;
|
||||||
memset(&destination, 0, sizeof(destination));
|
memset(&destination, 0, sizeof(destination));
|
||||||
destination.sa_family = AF_UNSPEC;
|
destination.sa_family = AF_UNSPEC;
|
||||||
// raw packet with ethernet header
|
// raw packet with ethernet header
|
||||||
memcpy(destination.sa_data, fPeer, sizeof(fPeer));
|
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||||
|
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
||||||
|
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||||
|
|
||||||
|
fState = PADR_SENT;
|
||||||
|
|
||||||
if(EthernetIfnet()->output(EthernetIfnet(), replyPacket, &destination,
|
if(EthernetIfnet()->output(EthernetIfnet(), replyPacket, &destination,
|
||||||
NULL) != B_OK) {
|
NULL) != B_OK) {
|
||||||
@@ -380,14 +449,12 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fState = PADR_SENT;
|
|
||||||
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case PADS:
|
case PADS:
|
||||||
if(fState != PADR_SENT
|
if(fState != PADR_SENT
|
||||||
|| memcmp(header->ethernetHeader.ether_shost, fPeer,
|
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
|
||||||
sizeof(fPeer))) {
|
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -400,14 +467,14 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber = 0)
|
|||||||
|
|
||||||
case PADT:
|
case PADT:
|
||||||
if(!IsUp()
|
if(!IsUp()
|
||||||
|| memcmp(header->ethernetHeader.ether_shost, fPeer,
|
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))
|
||||||
sizeof(fPeer))
|
|
||||||
|| header->sessionID != SessionID()) {
|
|| header->sessionID != SessionID()) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fState = INITIAL;
|
fState = INITIAL;
|
||||||
|
fAttempts = 0;
|
||||||
fSessionID = 0;
|
fSessionID = 0;
|
||||||
fNextTimeout = 0;
|
fNextTimeout = 0;
|
||||||
DownEvent();
|
DownEvent();
|
||||||
@@ -436,6 +503,8 @@ PPPoEDevice::Pulse()
|
|||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
// check if timed out
|
// check if timed out
|
||||||
if(system_time() >= fNextTimeout)
|
if(system_time() >= fNextTimeout) {
|
||||||
Up();
|
if(!Up())
|
||||||
|
UpFailedEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class PPPoEDevice : public PPPDevice {
|
|||||||
uint32 fHostUniq;
|
uint32 fHostUniq;
|
||||||
char *fACName, *fServiceName;
|
char *fACName, *fServiceName;
|
||||||
|
|
||||||
|
uint32 fAttempts;
|
||||||
bigtime_t fNextTimeout;
|
bigtime_t fNextTimeout;
|
||||||
pppoe_state fState;
|
pppoe_state fState;
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ static int32 host_uniq = 0;
|
|||||||
status_t std_ops(int32 op, ...);
|
status_t std_ops(int32 op, ...);
|
||||||
|
|
||||||
static BLocker lock;
|
static BLocker lock;
|
||||||
static List<PPPoEDevice*> devices;
|
static List<PPPoEDevice*> *devices;
|
||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
@@ -45,6 +45,30 @@ NewHostUniq()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
add_device(PPPoEDevice *device)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPoE: add_device()\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LockerHelper locker(lock);
|
||||||
|
devices->AddItem(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
remove_device(PPPoEDevice *device)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPoE: remove_device()\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LockerHelper locker(lock);
|
||||||
|
devices->RemoveItem(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
pppoe_input(struct mbuf *packet)
|
pppoe_input(struct mbuf *packet)
|
||||||
@@ -52,27 +76,43 @@ pppoe_input(struct mbuf *packet)
|
|||||||
if(!packet)
|
if(!packet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
// dump_packet(packet);
|
||||||
|
#endif
|
||||||
|
|
||||||
ifnet *sourceIfnet = packet->m_pkthdr.rcvif;
|
ifnet *sourceIfnet = packet->m_pkthdr.rcvif;
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
complete_pppoe_header *header = mtod(packet, complete_pppoe_header*);
|
||||||
PPPoEDevice *device;
|
PPPoEDevice *device;
|
||||||
|
|
||||||
LockerHelper locker(lock);
|
LockerHelper locker(lock);
|
||||||
|
|
||||||
for(int32 index = 0; index < devices.CountItems(); index++) {
|
for(int32 index = 0; index < devices->CountItems(); index++) {
|
||||||
device = devices.ItemAt(index);
|
device = devices->ItemAt(index);
|
||||||
|
|
||||||
if(device && device->EthernetIfnet() == sourceIfnet) {
|
if(device && device->EthernetIfnet() == sourceIfnet) {
|
||||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE
|
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE
|
||||||
&& header->sessionID == device->SessionID()) {
|
&& header->pppoeHeader.sessionID == device->SessionID()) {
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPoE: session packet\n");
|
||||||
|
#endif
|
||||||
device->Receive(packet);
|
device->Receive(packet);
|
||||||
return;
|
return;
|
||||||
} else if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE
|
} else if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC
|
||||||
&& header->code != PADI && header->code != PADR
|
&& header->pppoeHeader.code != PADI
|
||||||
|
&& header->pppoeHeader.code != PADR
|
||||||
&& !device->IsDown()) {
|
&& !device->IsDown()) {
|
||||||
DiscoveryPacket discovery(packet);
|
#if DEBUG
|
||||||
|
printf("PPPoE: discovery packet\n");
|
||||||
|
#endif
|
||||||
|
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||||
|
if(discovery.InitCheck() != B_OK) {
|
||||||
|
printf("PPPoE: received corrupted discovery packet!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ);
|
pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ);
|
||||||
if(tag && tag->length == 4
|
if(header->pppoeHeader.code == PADT || (tag && tag->length == 4
|
||||||
&& *((uint32*)tag->data) == device->HostUniq()) {
|
&& *((uint32*)tag->data) == device->HostUniq())) {
|
||||||
device->Receive(packet);
|
device->Receive(packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -96,21 +136,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 {
|
||||||
#if DEBUG
|
|
||||||
printf("PPPoE: add_to(): Adding to mainInterface\n");
|
|
||||||
#endif
|
|
||||||
device = new PPPoEDevice(mainInterface, settings);
|
device = new PPPoEDevice(mainInterface, settings);
|
||||||
success = mainInterface.SetDevice(device);
|
success = mainInterface.SetDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("PPPoE: add_to(): %s\n", success && device && device->InitCheck() == B_OK ? "OK" : "ERROR");
|
printf("PPPoE: add_to(): %s\n",
|
||||||
|
success && device && device->InitCheck() == B_OK ? "OK" : "ERROR");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return success && device && device->InitCheck() == B_OK;
|
return success && device && device->InitCheck() == B_OK;
|
||||||
@@ -142,6 +177,8 @@ std_ops(int32 op, ...)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
devices = new List<PPPoEDevice*>;
|
||||||
|
|
||||||
ethernet->set_pppoe_receiver(pppoe_input);
|
ethernet->set_pppoe_receiver(pppoe_input);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -150,6 +187,7 @@ std_ops(int32 op, ...)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
|
delete devices;
|
||||||
ethernet->unset_pppoe_receiver();
|
ethernet->unset_pppoe_receiver();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("PPPoE: Unregistered PPPoE receiver.\n");
|
printf("PPPoE: Unregistered PPPoE receiver.\n");
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
|
|
||||||
PPPConfigurePacket::PPPConfigurePacket(uint8 code)
|
PPPConfigurePacket::PPPConfigurePacket(uint8 code)
|
||||||
: fCode(code)
|
: fCode(code),
|
||||||
|
fID(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,20 +23,26 @@ PPPConfigurePacket::PPPConfigurePacket(struct mbuf *packet)
|
|||||||
// decode packet
|
// decode packet
|
||||||
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
||||||
|
|
||||||
|
SetID(header->id);
|
||||||
if(!SetCode(header->code))
|
if(!SetCode(header->code))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(header->length < 4)
|
uint16 length = ntohs(header->length);
|
||||||
|
|
||||||
|
if(length < 6 || length > packet->m_len)
|
||||||
return;
|
return;
|
||||||
// there are no items (or one corrupted item)
|
// there are no items (or one corrupted item)
|
||||||
|
|
||||||
int32 position = 0;
|
int32 position = 0;
|
||||||
ppp_configure_item *item;
|
ppp_configure_item *item;
|
||||||
|
|
||||||
while(position <= header->length - 4) {
|
while(position < length - 4) {
|
||||||
item = (ppp_configure_item*) (header->data + position);
|
item = (ppp_configure_item*) (header->data + position);
|
||||||
position += item->length;
|
if(item->length < 2)
|
||||||
|
return;
|
||||||
|
// found a corrupted item
|
||||||
|
|
||||||
|
position += item->length;
|
||||||
AddItem(item);
|
AddItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +71,7 @@ PPPConfigurePacket::SetCode(uint8 code)
|
|||||||
bool
|
bool
|
||||||
PPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index = -1)
|
PPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index = -1)
|
||||||
{
|
{
|
||||||
if(item->length < 2)
|
if(!item || item->length < 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ppp_configure_item *add = (ppp_configure_item*) malloc(item->length);
|
ppp_configure_item *add = (ppp_configure_item*) malloc(item->length);
|
||||||
@@ -125,7 +132,7 @@ PPPConfigurePacket::ItemWithType(uint8 type) const
|
|||||||
|
|
||||||
|
|
||||||
struct mbuf*
|
struct mbuf*
|
||||||
PPPConfigurePacket::ToMbuf(uint32 reserve = 0)
|
PPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve = 0)
|
||||||
{
|
{
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||||
packet->m_data += reserve;
|
packet->m_data += reserve;
|
||||||
@@ -133,15 +140,16 @@ PPPConfigurePacket::ToMbuf(uint32 reserve = 0)
|
|||||||
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
||||||
|
|
||||||
header->code = Code();
|
header->code = Code();
|
||||||
|
header->id = ID();
|
||||||
|
|
||||||
uint8 length = 0;
|
uint16 length = 0;
|
||||||
ppp_configure_item *item;
|
ppp_configure_item *item;
|
||||||
|
|
||||||
for(int32 index = 0; index < CountItems(); index++) {
|
for(int32 index = 0; index < CountItems(); index++) {
|
||||||
item = ItemAt(index);
|
item = ItemAt(index);
|
||||||
|
|
||||||
// make sure we have enough space left
|
// make sure we have enough space left
|
||||||
if(0xFF - length < item->length) {
|
if(MRU - length < item->length) {
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -150,8 +158,9 @@ PPPConfigurePacket::ToMbuf(uint32 reserve = 0)
|
|||||||
length += item->length;
|
length += item->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
header->length = length + 2;
|
length += 4;
|
||||||
packet->m_len = header->length;
|
header->length = htons(length);
|
||||||
|
packet->m_pkthdr.len = packet->m_len = length;
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,9 @@
|
|||||||
#include <PPPControl.h>
|
#include <PPPControl.h>
|
||||||
|
|
||||||
|
|
||||||
PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
|
PPPDevice::PPPDevice(const char *name, uint32 overhead, PPPInterface& interface,
|
||||||
driver_parameter *settings)
|
driver_parameter *settings)
|
||||||
: PPPLayer(name, PPP_DEVICE_LEVEL),
|
: PPPLayer(name, PPP_DEVICE_LEVEL, overhead),
|
||||||
fMTU(1500),
|
fMTU(1500),
|
||||||
fInterface(interface),
|
fInterface(interface),
|
||||||
fSettings(settings),
|
fSettings(settings),
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ status_t call_close_event_thread(void *data);
|
|||||||
|
|
||||||
PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
|
PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
|
||||||
PPPInterface *parent = NULL)
|
PPPInterface *parent = NULL)
|
||||||
: PPPLayer("PPPInterface", PPP_INTERFACE_LEVEL),
|
: PPPLayer("PPPInterface", PPP_INTERFACE_LEVEL, 2),
|
||||||
fID(ID),
|
fID(ID),
|
||||||
fSettings(dup_driver_settings(settings)),
|
fSettings(dup_driver_settings(settings)),
|
||||||
fIfnet(NULL),
|
fIfnet(NULL),
|
||||||
@@ -104,19 +104,25 @@ PPPInterface::PPPInterface(uint32 ID, const driver_settings *settings,
|
|||||||
// MRU
|
// MRU
|
||||||
_PPPMRUHandler *mruHandler =
|
_PPPMRUHandler *mruHandler =
|
||||||
new _PPPMRUHandler(*this);
|
new _PPPMRUHandler(*this);
|
||||||
if(!LCP().AddOptionHandler(mruHandler) || mruHandler->InitCheck() != B_OK)
|
if(!LCP().AddOptionHandler(mruHandler) || mruHandler->InitCheck() != B_OK) {
|
||||||
|
printf("PPPInterface: Could not add MRU handler!\n");
|
||||||
delete mruHandler;
|
delete mruHandler;
|
||||||
|
}
|
||||||
// authentication
|
// authentication
|
||||||
_PPPAuthenticationHandler *authenticationHandler =
|
_PPPAuthenticationHandler *authenticationHandler =
|
||||||
new _PPPAuthenticationHandler(*this);
|
new _PPPAuthenticationHandler(*this);
|
||||||
if(!LCP().AddOptionHandler(authenticationHandler)
|
if(!LCP().AddOptionHandler(authenticationHandler)
|
||||||
|| authenticationHandler->InitCheck() != B_OK)
|
|| authenticationHandler->InitCheck() != B_OK) {
|
||||||
|
printf("PPPInterface: Could not add authentication handler!\n");
|
||||||
delete authenticationHandler;
|
delete authenticationHandler;
|
||||||
|
}
|
||||||
// PFC
|
// PFC
|
||||||
_PPPPFCHandler *pfcHandler =
|
_PPPPFCHandler *pfcHandler =
|
||||||
new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this);
|
new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this);
|
||||||
if(!LCP().AddOptionHandler(pfcHandler) || pfcHandler->InitCheck() != B_OK)
|
if(!LCP().AddOptionHandler(pfcHandler) || pfcHandler->InitCheck() != B_OK) {
|
||||||
|
printf("PPPInterface: Could not add PFC handler!\n");
|
||||||
delete pfcHandler;
|
delete pfcHandler;
|
||||||
|
}
|
||||||
|
|
||||||
// set up dial delays
|
// set up dial delays
|
||||||
fDialRetryDelay = 3000;
|
fDialRetryDelay = 3000;
|
||||||
@@ -269,10 +275,6 @@ PPPInterface::Delete()
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::InitCheck() const
|
PPPInterface::InitCheck() const
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
printf("PPPInterface: InitCheck(): 0x%lX\n", fInitStatus);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(fInitStatus != B_OK)
|
if(fInitStatus != B_OK)
|
||||||
return fInitStatus;
|
return fInitStatus;
|
||||||
|
|
||||||
@@ -610,10 +612,6 @@ PPPInterface::CountProtocols() const
|
|||||||
for(; protocol; protocol = protocol->NextProtocol())
|
for(; protocol; protocol = protocol->NextProtocol())
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
printf("PPPInterface: CountProtocols(): %ld\n", count);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,10 +619,6 @@ PPPInterface::CountProtocols() const
|
|||||||
PPPProtocol*
|
PPPProtocol*
|
||||||
PPPInterface::ProtocolAt(int32 index) const
|
PPPInterface::ProtocolAt(int32 index) const
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
printf("PPPInterface: ProtocolAt(%ld)\n", index);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PPPProtocol *protocol = FirstProtocol();
|
PPPProtocol *protocol = FirstProtocol();
|
||||||
|
|
||||||
int32 currentIndex = 0;
|
int32 currentIndex = 0;
|
||||||
@@ -638,10 +632,6 @@ PPPInterface::ProtocolAt(int32 index) const
|
|||||||
PPPProtocol*
|
PPPProtocol*
|
||||||
PPPInterface::ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) const
|
PPPInterface::ProtocolFor(uint16 protocolNumber, PPPProtocol *start = NULL) const
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
printf("PPPInterface: ProtocolFor(0x%X)\n", protocolNumber);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PPPProtocol *current = start ? start : FirstProtocol();
|
PPPProtocol *current = start ? start : FirstProtocol();
|
||||||
|
|
||||||
for(; current; current = current->NextProtocol()) {
|
for(; current; current = current->NextProtocol()) {
|
||||||
@@ -838,33 +828,16 @@ PPPInterface::Up()
|
|||||||
// is waiting for new reports)
|
// is waiting for new reports)
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
if(IsUp()) {
|
|
||||||
// lock needs timeout because destructor could have locked the interface
|
|
||||||
while(!fLock.LockWithTimeout(100000) != B_NO_ERROR)
|
|
||||||
if(fDeleteCounter > 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if(me == fUpThread) {
|
|
||||||
fDialRetry = 0;
|
|
||||||
fUpThread = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
|
|
||||||
fLock.Unlock();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A wrong code usually happens when the redial thread gets notified
|
// A wrong code usually happens when the redial thread gets notified
|
||||||
// of a Down() request. In that case a report will follow soon, so
|
// of a Down() request. In that case a report will follow soon, so
|
||||||
// this can be ignored.
|
// this can be ignored.
|
||||||
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
|
if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if DEBUG
|
//#if DEBUG
|
||||||
printf("PPPInterface::Up(): Report: Type = %ld Code = %ld\n", report.type,
|
// printf("PPPInterface::Up(): Report: Type = %ld Code = %ld\n", report.type,
|
||||||
report.code);
|
// report.code);
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
if(IsUp()) {
|
if(IsUp()) {
|
||||||
if(me == fUpThread) {
|
if(me == fUpThread) {
|
||||||
@@ -947,19 +920,27 @@ PPPInterface::Up()
|
|||||||
// I am the thread for the real task
|
// I am the thread for the real task
|
||||||
if(report.code == PPP_REPORT_DEVICE_UP_FAILED) {
|
if(report.code == PPP_REPORT_DEVICE_UP_FAILED) {
|
||||||
if(fDialRetry >= fDialRetriesLimit) {
|
if(fDialRetry >= fDialRetriesLimit) {
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPInterface::Up(): DEVICE_UP_FAILED: >=maxretries!\n");
|
||||||
|
#endif
|
||||||
fDialRetry = 0;
|
fDialRetry = 0;
|
||||||
fUpThread = -1;
|
fUpThread = -1;
|
||||||
|
|
||||||
if(!DoesDialOnDemand()
|
if(!DoesDialOnDemand())
|
||||||
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
|
||||||
Delete();
|
Delete();
|
||||||
|
|
||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
|
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPInterface::Up(): DEVICE_UP_FAILED: <maxretries\n");
|
||||||
|
#endif
|
||||||
++fDialRetry;
|
++fDialRetry;
|
||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPInterface::Up(): DEVICE_UP_FAILED: replied\n");
|
||||||
|
#endif
|
||||||
Redial(DialRetryDelay());
|
Redial(DialRetryDelay());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -977,8 +958,7 @@ PPPInterface::Up()
|
|||||||
PPP_REPLY(sender, B_OK);
|
PPP_REPLY(sender, B_OK);
|
||||||
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
|
ReportManager().DisableReports(PPP_CONNECTION_REPORT, me);
|
||||||
|
|
||||||
if(!DoesDialOnDemand()
|
if(!DoesDialOnDemand())
|
||||||
&& report.code != PPP_REPORT_DOWN_SUCCESSFUL)
|
|
||||||
Delete();
|
Delete();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1180,14 +1160,8 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test whether are going down
|
|
||||||
if(Phase() == PPP_TERMINATION_PHASE) {
|
|
||||||
m_freem(packet);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// go up if DialOnDemand enabled and we are down
|
// go up if DialOnDemand enabled and we are down
|
||||||
if(DoesDialOnDemand()
|
if(protocolNumber != PPP_LCP_PROTOCOL && DoesDialOnDemand()
|
||||||
&& (Phase() == PPP_DOWN_PHASE
|
&& (Phase() == PPP_DOWN_PHASE
|
||||||
|| Phase() == PPP_ESTABLISHMENT_PHASE)
|
|| Phase() == PPP_ESTABLISHMENT_PHASE)
|
||||||
&& !Up()) {
|
&& !Up()) {
|
||||||
@@ -1229,8 +1203,6 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
*header = protocolNumber;
|
*header = protocolNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
fIdleSince = real_time_clock();
|
|
||||||
|
|
||||||
// pass to device/children
|
// pass to device/children
|
||||||
if(!IsMultilink() || Parent()) {
|
if(!IsMultilink() || Parent()) {
|
||||||
// check if packet is too big for device
|
// check if packet is too big for device
|
||||||
@@ -1260,6 +1232,8 @@ PPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
if(!packet)
|
if(!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
fIdleSince = real_time_clock();
|
||||||
|
|
||||||
int32 result = PPP_REJECTED;
|
int32 result = PPP_REJECTED;
|
||||||
// assume we have no handler
|
// assume we have no handler
|
||||||
|
|
||||||
@@ -1334,23 +1308,17 @@ PPPInterface::ReceiveFromDevice(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPInterface::Pulse()
|
PPPInterface::Pulse()
|
||||||
{
|
{
|
||||||
if(fDeleteCounter > 0)
|
|
||||||
return;
|
|
||||||
// we have no pulse when we are dead ;)
|
|
||||||
|
|
||||||
// check our idle time and disconnect if needed
|
|
||||||
if(fDisconnectAfterIdleSince > 0 && fIdleSince != 0
|
|
||||||
&& fIdleSince - real_time_clock() >= fDisconnectAfterIdleSince) {
|
|
||||||
StateMachine().CloseEvent();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Device())
|
if(Device())
|
||||||
Device()->Pulse();
|
Device()->Pulse();
|
||||||
|
|
||||||
PPPProtocol *protocol = FirstProtocol();
|
PPPProtocol *protocol = FirstProtocol();
|
||||||
for(; protocol; protocol = protocol->NextProtocol())
|
for(; protocol; protocol = protocol->NextProtocol())
|
||||||
protocol->Pulse();
|
protocol->Pulse();
|
||||||
|
|
||||||
|
// check our idle time and disconnect if needed
|
||||||
|
if(fDisconnectAfterIdleSince > 0 && fIdleSince != 0
|
||||||
|
&& fIdleSince - real_time_clock() >= fDisconnectAfterIdleSince)
|
||||||
|
StateMachine().CloseEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1590,12 +1558,9 @@ redial_thread(void *data)
|
|||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// Function: interface_deleter_thread
|
// Function: interface_deleter_thread
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// The destructor is private, so this thread function cannot delete our interface.
|
class PPPInterfaceAccess {
|
||||||
// To solve this problem we create a 'fake' class PPPManager (friend of PPPInterface)
|
|
||||||
// which is only defined here (the real class is defined in the ppp interface module).
|
|
||||||
class PPPManager {
|
|
||||||
public:
|
public:
|
||||||
PPPManager() {}
|
PPPInterfaceAccess() {}
|
||||||
|
|
||||||
void Delete(PPPInterface *interface)
|
void Delete(PPPInterface *interface)
|
||||||
{ delete interface; }
|
{ delete interface; }
|
||||||
@@ -1623,8 +1588,8 @@ class PPPManager {
|
|||||||
status_t
|
status_t
|
||||||
interface_deleter_thread(void *data)
|
interface_deleter_thread(void *data)
|
||||||
{
|
{
|
||||||
PPPManager manager;
|
PPPInterfaceAccess access;
|
||||||
manager.Delete((PPPInterface*) data);
|
access.Delete((PPPInterface*) data);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -1633,8 +1598,8 @@ interface_deleter_thread(void *data)
|
|||||||
status_t
|
status_t
|
||||||
call_open_event_thread(void *data)
|
call_open_event_thread(void *data)
|
||||||
{
|
{
|
||||||
PPPManager manager;
|
PPPInterfaceAccess access;
|
||||||
manager.CallOpenEvent((PPPInterface*) data);
|
access.CallOpenEvent((PPPInterface*) data);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -1643,8 +1608,8 @@ call_open_event_thread(void *data)
|
|||||||
status_t
|
status_t
|
||||||
call_close_event_thread(void *data)
|
call_close_event_thread(void *data)
|
||||||
{
|
{
|
||||||
PPPManager manager;
|
PPPInterfaceAccess access;
|
||||||
manager.CallCloseEvent((PPPInterface*) data);
|
access.CallCloseEvent((PPPInterface*) data);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,11 +175,14 @@ PPPLCP::LCPExtensionFor(uint8 code, int32 *start = NULL) const
|
|||||||
uint32
|
uint32
|
||||||
PPPLCP::AdditionalOverhead() const
|
PPPLCP::AdditionalOverhead() const
|
||||||
{
|
{
|
||||||
uint32 overhead = 0;
|
uint32 overhead = Interface().Overhead();
|
||||||
|
|
||||||
if(Target())
|
if(Target())
|
||||||
overhead += Target()->Overhead();
|
overhead += Target()->Overhead();
|
||||||
|
|
||||||
|
if(Interface().Device())
|
||||||
|
overhead += Interface().Device()->Overhead();
|
||||||
|
|
||||||
return overhead;
|
return overhead;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,17 +222,21 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
|
|
||||||
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
|
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
|
||||||
|
|
||||||
// adjust length (remove padding)
|
// remove padding
|
||||||
int32 length = packet->m_len;
|
int32 length = packet->m_len;
|
||||||
if(packet->m_flags & M_PKTHDR)
|
if(packet->m_flags & M_PKTHDR)
|
||||||
length = packet->m_pkthdr.len;
|
length = packet->m_pkthdr.len;
|
||||||
if(length - ntohs(data->length) != 0)
|
#if DEBUG
|
||||||
m_adj(packet, length);
|
printf("LCP::Recv: len=%ld;datalen=%d\n", length, ntohs(data->length));
|
||||||
|
#endif
|
||||||
|
length -= ntohs(data->length);
|
||||||
|
if(length)
|
||||||
|
m_adj(packet, -length);
|
||||||
|
|
||||||
struct mbuf *copy = m_gethdr(MT_DATA);
|
struct mbuf *copy = m_gethdr(MT_DATA);
|
||||||
if(copy) {
|
if(copy) {
|
||||||
copy->m_data += AdditionalOverhead();
|
copy->m_data += AdditionalOverhead();
|
||||||
copy->m_len = packet->m_len;
|
copy->m_pkthdr.len = copy->m_len = packet->m_len;
|
||||||
memcpy(copy->m_data, packet->m_data, copy->m_len);
|
memcpy(copy->m_data, packet->m_data, copy->m_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PPPLayer::PPPLayer(const char *name, ppp_level level)
|
PPPLayer::PPPLayer(const char *name, ppp_level level, uint32 overhead)
|
||||||
: fInitStatus(B_OK),
|
: fInitStatus(B_OK),
|
||||||
|
fOverhead(overhead),
|
||||||
fLevel(level),
|
fLevel(level),
|
||||||
fNext(NULL)
|
fNext(NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type,
|
PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type,
|
||||||
PPPInterface& interface, driver_parameter *settings)
|
PPPInterface& interface, driver_parameter *settings)
|
||||||
: fType(type),
|
: fInitStatus(B_OK),
|
||||||
|
fType(type),
|
||||||
fInterface(interface),
|
fInterface(interface),
|
||||||
fSettings(settings),
|
fSettings(settings),
|
||||||
fEnabled(true)
|
fEnabled(true)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ PPPProtocol::PPPProtocol(const char *name, ppp_phase activationPhase,
|
|||||||
uint32 overhead, PPPInterface& interface,
|
uint32 overhead, PPPInterface& interface,
|
||||||
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
|
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
|
||||||
const char *type = NULL, PPPOptionHandler *optionHandler = NULL)
|
const char *type = NULL, PPPOptionHandler *optionHandler = NULL)
|
||||||
: PPPLayer(name, level),
|
: PPPLayer(name, level, overhead),
|
||||||
fActivationPhase(activationPhase),
|
fActivationPhase(activationPhase),
|
||||||
fProtocolNumber(protocolNumber),
|
fProtocolNumber(protocolNumber),
|
||||||
fAddressFamily(addressFamily),
|
fAddressFamily(addressFamily),
|
||||||
|
|||||||
@@ -10,6 +10,14 @@
|
|||||||
|
|
||||||
#include <KPPPUtils.h>
|
#include <KPPPUtils.h>
|
||||||
|
|
||||||
|
#ifdef _KERNEL_MODE
|
||||||
|
#include <KernelExport.h>
|
||||||
|
#define spawn_thread spawn_kernel_thread
|
||||||
|
#define printf dprintf
|
||||||
|
#else
|
||||||
|
#include <cstdio>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PPPReportManager::PPPReportManager(BLocker& lock)
|
PPPReportManager::PPPReportManager(BLocker& lock)
|
||||||
: fLock(lock)
|
: fLock(lock)
|
||||||
@@ -79,6 +87,11 @@ PPPReportManager::DoesReport(ppp_report_type type, thread_id thread)
|
|||||||
bool
|
bool
|
||||||
PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 length)
|
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);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(length > PPP_REPORT_DATA_LIMIT)
|
if(length > PPP_REPORT_DATA_LIMIT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -112,6 +125,11 @@ PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 len
|
|||||||
result = send_data_with_timeout(request->thread, PPP_REPORT_CODE, &report,
|
result = send_data_with_timeout(request->thread, PPP_REPORT_CODE, &report,
|
||||||
sizeof(report), PPP_REPORT_TIMEOUT);
|
sizeof(report), PPP_REPORT_TIMEOUT);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if(result == B_TIMED_OUT)
|
||||||
|
printf("PPPReportManager::Report(): timed out sending\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
if(result == B_BAD_THREAD_ID || result == B_NO_MEMORY) {
|
if(result == B_BAD_THREAD_ID || result == B_NO_MEMORY) {
|
||||||
fReportRequests.RemoveItem(request);
|
fReportRequests.RemoveItem(request);
|
||||||
--index;
|
--index;
|
||||||
@@ -139,6 +157,10 @@ PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 len
|
|||||||
|
|
||||||
if(result == B_OK && code != B_OK)
|
if(result == B_OK && code != B_OK)
|
||||||
acceptable = false;
|
acceptable = false;
|
||||||
|
#if DEBUG
|
||||||
|
if(result == B_TIMED_OUT)
|
||||||
|
printf("PPPReportManager::Report(): reply timed out\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,5 +170,9 @@ PPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 len
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPReportManager::Report(): returning: %s\n", acceptable?"true":"false");
|
||||||
|
#endif
|
||||||
|
|
||||||
return acceptable;
|
return acceptable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,16 @@
|
|||||||
#include <core_funcs.h>
|
#include <core_funcs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _KERNEL_MODE
|
||||||
|
#define spawn_thread spawn_kernel_thread
|
||||||
|
#define printf dprintf
|
||||||
|
#elif DEBUG
|
||||||
|
#include <cstdio>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define PPP_STATE_MACHINE_TIMEOUT 3000000
|
#define PPP_STATE_MACHINE_TIMEOUT 3000000
|
||||||
|
// 3 seconds
|
||||||
|
|
||||||
|
|
||||||
PPPStateMachine::PPPStateMachine(PPPInterface& interface)
|
PPPStateMachine::PPPStateMachine(PPPInterface& interface)
|
||||||
@@ -61,6 +70,10 @@ PPPStateMachine::NextID()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::NewState(ppp_state next)
|
PPPStateMachine::NewState(ppp_state next)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: NewState(%d) state=%d\n", next, State());
|
||||||
|
#endif
|
||||||
|
|
||||||
// maybe we do not need the timer anymore
|
// maybe we do not need the timer anymore
|
||||||
if(next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE)
|
if(next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE)
|
||||||
fNextTimeout = 0;
|
fNextTimeout = 0;
|
||||||
@@ -75,6 +88,11 @@ PPPStateMachine::NewState(ppp_state next)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::NewPhase(ppp_phase next)
|
PPPStateMachine::NewPhase(ppp_phase next)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if(next <= PPP_ESTABLISHMENT_PHASE || next == PPP_ESTABLISHED_PHASE)
|
||||||
|
printf("PPPSM: NewPhase(%d) phase=%d\n", next, Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
// there is nothing after established phase and nothing before down phase
|
// there is nothing after established phase and nothing before down phase
|
||||||
if(next > PPP_ESTABLISHED_PHASE)
|
if(next > PPP_ESTABLISHED_PHASE)
|
||||||
next = PPP_ESTABLISHED_PHASE;
|
next = PPP_ESTABLISHED_PHASE;
|
||||||
@@ -113,6 +131,11 @@ PPPStateMachine::NewPhase(ppp_phase next)
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::Reconfigure()
|
PPPStateMachine::Reconfigure()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: Reconfigure() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(State() < PPP_REQ_SENT_STATE)
|
if(State() < PPP_REQ_SENT_STATE)
|
||||||
@@ -133,6 +156,11 @@ PPPStateMachine::Reconfigure()
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::SendEchoRequest()
|
PPPStateMachine::SendEchoRequest()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: SendEchoRequest() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(State() != PPP_OPENED_STATE)
|
if(State() != PPP_OPENED_STATE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -141,7 +169,7 @@ PPPStateMachine::SendEchoRequest()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
packet->m_data += LCP().AdditionalOverhead();
|
packet->m_data += LCP().AdditionalOverhead();
|
||||||
packet->m_len = 8;
|
packet->m_pkthdr.len = packet->m_len = 8;
|
||||||
// echo requests are at least eight bytes long
|
// echo requests are at least eight bytes long
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
||||||
@@ -158,6 +186,11 @@ PPPStateMachine::SendEchoRequest()
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::SendDiscardRequest()
|
PPPStateMachine::SendDiscardRequest()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: SendDiscardRequest() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(State() != PPP_OPENED_STATE)
|
if(State() != PPP_OPENED_STATE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -166,7 +199,7 @@ PPPStateMachine::SendDiscardRequest()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
packet->m_data += LCP().AdditionalOverhead();
|
packet->m_data += LCP().AdditionalOverhead();
|
||||||
packet->m_len = 8;
|
packet->m_pkthdr.len = packet->m_len = 8;
|
||||||
// discard requests are at least eight bytes long
|
// discard requests are at least eight bytes long
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
||||||
@@ -183,6 +216,11 @@ PPPStateMachine::SendDiscardRequest()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::LocalAuthenticationRequested()
|
PPPStateMachine::LocalAuthenticationRequested()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: LocalAuthenticationRequested() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
fLocalAuthenticationStatus = PPP_AUTHENTICATING;
|
fLocalAuthenticationStatus = PPP_AUTHENTICATING;
|
||||||
@@ -194,11 +232,19 @@ PPPStateMachine::LocalAuthenticationRequested()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::LocalAuthenticationAccepted(const char *name)
|
PPPStateMachine::LocalAuthenticationAccepted(const char *name)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: LocalAuthenticationAccepted() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
fLocalAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
fLocalAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||||
free(fLocalAuthenticationName);
|
free(fLocalAuthenticationName);
|
||||||
|
if(name)
|
||||||
fLocalAuthenticationName = strdup(name);
|
fLocalAuthenticationName = strdup(name);
|
||||||
|
else
|
||||||
|
fLocalAuthenticationName = NULL;
|
||||||
|
|
||||||
Interface().Report(PPP_CONNECTION_REPORT,
|
Interface().Report(PPP_CONNECTION_REPORT,
|
||||||
PPP_REPORT_LOCAL_AUTHENTICATION_SUCCESSFUL, NULL, 0);
|
PPP_REPORT_LOCAL_AUTHENTICATION_SUCCESSFUL, NULL, 0);
|
||||||
@@ -208,17 +254,30 @@ PPPStateMachine::LocalAuthenticationAccepted(const char *name)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::LocalAuthenticationDenied(const char *name)
|
PPPStateMachine::LocalAuthenticationDenied(const char *name)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: LocalAuthenticationDenied() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
fLocalAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
|
fLocalAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
|
||||||
free(fLocalAuthenticationName);
|
free(fLocalAuthenticationName);
|
||||||
|
if(name)
|
||||||
fLocalAuthenticationName = strdup(name);
|
fLocalAuthenticationName = strdup(name);
|
||||||
|
else
|
||||||
|
fLocalAuthenticationName = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::PeerAuthenticationRequested()
|
PPPStateMachine::PeerAuthenticationRequested()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: PeerAuthenticationRequested() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
fPeerAuthenticationStatus = PPP_AUTHENTICATING;
|
fPeerAuthenticationStatus = PPP_AUTHENTICATING;
|
||||||
@@ -230,11 +289,19 @@ PPPStateMachine::PeerAuthenticationRequested()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::PeerAuthenticationAccepted(const char *name)
|
PPPStateMachine::PeerAuthenticationAccepted(const char *name)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: PeerAuthenticationAccepted() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
fPeerAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
fPeerAuthenticationStatus = PPP_AUTHENTICATION_SUCCESSFUL;
|
||||||
free(fPeerAuthenticationName);
|
free(fPeerAuthenticationName);
|
||||||
|
if(name)
|
||||||
fPeerAuthenticationName = strdup(name);
|
fPeerAuthenticationName = strdup(name);
|
||||||
|
else
|
||||||
|
fPeerAuthenticationName = NULL;
|
||||||
|
|
||||||
Interface().Report(PPP_CONNECTION_REPORT,
|
Interface().Report(PPP_CONNECTION_REPORT,
|
||||||
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL, NULL, 0);
|
PPP_REPORT_PEER_AUTHENTICATION_SUCCESSFUL, NULL, 0);
|
||||||
@@ -244,11 +311,19 @@ PPPStateMachine::PeerAuthenticationAccepted(const char *name)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::PeerAuthenticationDenied(const char *name)
|
PPPStateMachine::PeerAuthenticationDenied(const char *name)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: PeerAuthenticationDenied() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
fPeerAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
|
fPeerAuthenticationStatus = PPP_AUTHENTICATION_FAILED;
|
||||||
free(fPeerAuthenticationName);
|
free(fPeerAuthenticationName);
|
||||||
|
if(name)
|
||||||
fPeerAuthenticationName = strdup(name);
|
fPeerAuthenticationName = strdup(name);
|
||||||
|
else
|
||||||
|
fPeerAuthenticationName = NULL;
|
||||||
|
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
}
|
}
|
||||||
@@ -257,6 +332,11 @@ PPPStateMachine::PeerAuthenticationDenied(const char *name)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::UpFailedEvent(PPPInterface& interface)
|
PPPStateMachine::UpFailedEvent(PPPInterface& interface)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: UpFailedEvent(interface) state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// log that an interface did not go up
|
// log that an interface did not go up
|
||||||
}
|
}
|
||||||
@@ -265,6 +345,11 @@ PPPStateMachine::UpFailedEvent(PPPInterface& interface)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::UpEvent(PPPInterface& interface)
|
PPPStateMachine::UpEvent(PPPInterface& interface)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: UpEvent(interface) state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(Phase() <= PPP_TERMINATION_PHASE) {
|
if(Phase() <= PPP_TERMINATION_PHASE) {
|
||||||
@@ -290,6 +375,11 @@ PPPStateMachine::UpEvent(PPPInterface& interface)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::DownEvent(PPPInterface& interface)
|
PPPStateMachine::DownEvent(PPPInterface& interface)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: DownEvent(interface) state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
uint32 MRU = 0;
|
uint32 MRU = 0;
|
||||||
@@ -331,6 +421,11 @@ PPPStateMachine::DownEvent(PPPInterface& interface)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::UpFailedEvent(PPPProtocol *protocol)
|
PPPStateMachine::UpFailedEvent(PPPProtocol *protocol)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: UpFailedEvent(protocol) state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if((protocol->Flags() & PPP_NOT_IMPORTANT) == 0) {
|
if((protocol->Flags() & PPP_NOT_IMPORTANT) == 0) {
|
||||||
if(Interface().Mode() == PPP_CLIENT_MODE) {
|
if(Interface().Mode() == PPP_CLIENT_MODE) {
|
||||||
// pretend we lost connection
|
// pretend we lost connection
|
||||||
@@ -351,6 +446,11 @@ PPPStateMachine::UpFailedEvent(PPPProtocol *protocol)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::UpEvent(PPPProtocol *protocol)
|
PPPStateMachine::UpEvent(PPPProtocol *protocol)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: UpEvent(protocol) state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(Phase() >= PPP_ESTABLISHMENT_PHASE)
|
if(Phase() >= PPP_ESTABLISHMENT_PHASE)
|
||||||
@@ -361,6 +461,10 @@ PPPStateMachine::UpEvent(PPPProtocol *protocol)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::DownEvent(PPPProtocol *protocol)
|
PPPStateMachine::DownEvent(PPPProtocol *protocol)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: DownEvent(protocol) state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -372,6 +476,11 @@ PPPStateMachine::DownEvent(PPPProtocol *protocol)
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::TLSNotify()
|
PPPStateMachine::TLSNotify()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: TLSNotify() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(State() == PPP_STARTING_STATE) {
|
if(State() == PPP_STARTING_STATE) {
|
||||||
@@ -392,10 +501,15 @@ PPPStateMachine::TLSNotify()
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::TLFNotify()
|
PPPStateMachine::TLFNotify()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: TLFNotify() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
// from now on no packets may be sent to the device
|
NewPhase(PPP_TERMINATION_PHASE);
|
||||||
NewPhase(PPP_DOWN_PHASE);
|
// tell DownEvent() that it may create a connection-lost-report
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -404,29 +518,28 @@ PPPStateMachine::TLFNotify()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::UpFailedEvent()
|
PPPStateMachine::UpFailedEvent()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: UpFailedEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
case PPP_STARTING_STATE:
|
case PPP_STARTING_STATE:
|
||||||
// TLSNotify() sets establishment phase
|
#if DEBUG
|
||||||
if(Phase() != PPP_ESTABLISHMENT_PHASE) {
|
printf("PPPSM::UpFailedEvent(): Reporting...\n");
|
||||||
// there must be a BUG in the device add-on or someone is trying to
|
#endif
|
||||||
// fool us (UpEvent() is public) as we did not request the device
|
|
||||||
// to go up
|
|
||||||
IllegalEvent(PPP_UP_FAILED_EVENT);
|
|
||||||
NewState(PPP_INITIAL_STATE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_DEVICE_UP_FAILED,
|
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_DEVICE_UP_FAILED,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
|
||||||
if(Interface().Parent())
|
if(Interface().Parent())
|
||||||
Interface().Parent()->StateMachine().UpFailedEvent(Interface());
|
Interface().Parent()->StateMachine().UpFailedEvent(Interface());
|
||||||
|
|
||||||
NewPhase(PPP_DOWN_PHASE);
|
NewPhase(PPP_DOWN_PHASE);
|
||||||
// tell DownEvent() that it should not create a connection-lost-report
|
// tell DownEvent() that it should not create a connection-lost-report
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM::UpFailedEvent(): Calling DownEvent()\n");
|
||||||
|
#endif
|
||||||
DownEvent();
|
DownEvent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -439,6 +552,11 @@ PPPStateMachine::UpFailedEvent()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::UpEvent()
|
PPPStateMachine::UpEvent()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: UpEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
// This call is public, thus, it might not only be called by the device.
|
// This call is public, thus, it might not only be called by the device.
|
||||||
// We must recognize these attempts to fool us and handle them correctly.
|
// We must recognize these attempts to fool us and handle them correctly.
|
||||||
|
|
||||||
@@ -499,6 +617,11 @@ PPPStateMachine::UpEvent()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::DownEvent()
|
PPPStateMachine::DownEvent()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: DownEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(Interface().Device() && Interface().Device()->IsUp())
|
if(Interface().Device() && Interface().Device()->IsUp())
|
||||||
@@ -511,6 +634,11 @@ PPPStateMachine::DownEvent()
|
|||||||
Interface().fIdleSince = 0;
|
Interface().fIdleSince = 0;
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
|
// XXX: this does not belong to the standard, but may happen in our
|
||||||
|
// implementation
|
||||||
|
case PPP_STARTING_STATE:
|
||||||
|
break;
|
||||||
|
|
||||||
case PPP_CLOSED_STATE:
|
case PPP_CLOSED_STATE:
|
||||||
case PPP_CLOSING_STATE:
|
case PPP_CLOSING_STATE:
|
||||||
NewState(PPP_INITIAL_STATE);
|
NewState(PPP_INITIAL_STATE);
|
||||||
@@ -590,8 +718,17 @@ PPPStateMachine::DownEvent()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::OpenEvent()
|
PPPStateMachine::OpenEvent()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: OpenEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
// reset all handlers
|
||||||
|
DownProtocols();
|
||||||
|
ResetLCPHandlers();
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
case PPP_INITIAL_STATE:
|
case PPP_INITIAL_STATE:
|
||||||
if(!Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_GOING_UP, NULL, 0))
|
if(!Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_GOING_UP, NULL, 0))
|
||||||
@@ -644,6 +781,11 @@ PPPStateMachine::OpenEvent()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::CloseEvent()
|
PPPStateMachine::CloseEvent()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: CloseEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(Interface().IsMultilink() && !Interface().Parent()) {
|
if(Interface().IsMultilink() && !Interface().Parent()) {
|
||||||
@@ -708,6 +850,11 @@ PPPStateMachine::CloseEvent()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::TOGoodEvent()
|
PPPStateMachine::TOGoodEvent()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: TOGoodEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
@@ -736,6 +883,11 @@ PPPStateMachine::TOGoodEvent()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::TOBadEvent()
|
PPPStateMachine::TOBadEvent()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: TOBadEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
@@ -766,6 +918,11 @@ PPPStateMachine::TOBadEvent()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
PPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RCRGoodEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
@@ -823,6 +980,11 @@ PPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
PPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RCRBadEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
@@ -879,6 +1041,11 @@ PPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RCAEvent(struct mbuf *packet)
|
PPPStateMachine::RCAEvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RCAEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
||||||
@@ -954,6 +1121,11 @@ PPPStateMachine::RCAEvent(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RCNEvent(struct mbuf *packet)
|
PPPStateMachine::RCNEvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RCNEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
||||||
@@ -1032,6 +1204,11 @@ PPPStateMachine::RCNEvent(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RTREvent(struct mbuf *packet)
|
PPPStateMachine::RTREvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RTREvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
// we should not use the same ID as the peer
|
// we should not use the same ID as the peer
|
||||||
@@ -1080,6 +1257,11 @@ PPPStateMachine::RTREvent(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RTAEvent(struct mbuf *packet)
|
PPPStateMachine::RTAEvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RTAEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
if(fTerminateID != mtod(packet, ppp_lcp_packet*)->id) {
|
if(fTerminateID != mtod(packet, ppp_lcp_packet*)->id) {
|
||||||
@@ -1135,6 +1317,11 @@ void
|
|||||||
PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
||||||
uint8 code = PPP_PROTOCOL_REJECT)
|
uint8 code = PPP_PROTOCOL_REJECT)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RUCEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
@@ -1155,6 +1342,11 @@ PPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RXJGoodEvent(struct mbuf *packet)
|
PPPStateMachine::RXJGoodEvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RXJGoodEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
// This method does not m_freem(packet) because the acceptable rejects are
|
// This method does not m_freem(packet) because the acceptable rejects are
|
||||||
// also passed to the parent. RXJEvent() will m_freem(packet) when needed.
|
// also passed to the parent. RXJEvent() will m_freem(packet) when needed.
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
@@ -1179,6 +1371,11 @@ PPPStateMachine::RXJGoodEvent(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
PPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RXJBadEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
switch(State()) {
|
switch(State()) {
|
||||||
@@ -1227,6 +1424,11 @@ PPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RXREvent(struct mbuf *packet)
|
PPPStateMachine::RXREvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RXREvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
ppp_lcp_packet *echo = mtod(packet, ppp_lcp_packet*);
|
ppp_lcp_packet *echo = mtod(packet, ppp_lcp_packet*);
|
||||||
|
|
||||||
if(echo->code == PPP_ECHO_REPLY && echo->id != fEchoID) {
|
if(echo->code == PPP_ECHO_REPLY && echo->id != fEchoID) {
|
||||||
@@ -1258,6 +1460,11 @@ PPPStateMachine::RXREvent(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::TimerEvent()
|
PPPStateMachine::TimerEvent()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if(fNextTimeout != 0)
|
||||||
|
printf("PPPSM: TimerEvent()\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
if(fNextTimeout == 0 || fNextTimeout > system_time())
|
if(fNextTimeout == 0 || fNextTimeout > system_time())
|
||||||
return;
|
return;
|
||||||
@@ -1295,8 +1502,14 @@ PPPStateMachine::TimerEvent()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RCREvent(struct mbuf *packet)
|
PPPStateMachine::RCREvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
PPPConfigurePacket request(packet), nak(PPP_CONFIGURE_NAK),
|
#if DEBUG
|
||||||
reject(PPP_CONFIGURE_REJECT);
|
printf("PPPSM: RCREvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PPPConfigurePacket request(packet);
|
||||||
|
PPPConfigurePacket nak(PPP_CONFIGURE_NAK);
|
||||||
|
PPPConfigurePacket reject(PPP_CONFIGURE_REJECT);
|
||||||
|
|
||||||
// we should not use the same id as the peer
|
// we should not use the same id as the peer
|
||||||
if(fID == mtod(packet, ppp_lcp_packet*)->id)
|
if(fID == mtod(packet, ppp_lcp_packet*)->id)
|
||||||
@@ -1313,11 +1526,15 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
|
optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
|
||||||
|
|
||||||
if(!optionHandler || !optionHandler->IsEnabled()) {
|
if(!optionHandler || !optionHandler->IsEnabled()) {
|
||||||
|
printf("PPPSM::RCREvent(): unknown type:%d\n", request.ItemAt(index)->type);
|
||||||
// unhandled items should be added to the reject
|
// unhandled items should be added to the reject
|
||||||
reject.AddItem(request.ItemAt(index));
|
reject.AddItem(request.ItemAt(index));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM::RCREvent(): OH=%s\n", optionHandler->Name());
|
||||||
|
#endif
|
||||||
result = optionHandler->ParseRequest(request, index, nak, reject);
|
result = optionHandler->ParseRequest(request, index, nak, reject);
|
||||||
|
|
||||||
if(result == PPP_UNHANDLED) {
|
if(result == PPP_UNHANDLED) {
|
||||||
@@ -1327,6 +1544,7 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
} else if(result != B_OK) {
|
} else if(result != B_OK) {
|
||||||
// the request contains a value that has been sent more than
|
// the request contains a value that has been sent more than
|
||||||
// once or the value is corrupted
|
// once or the value is corrupted
|
||||||
|
printf("PPPSM::RCREvent(): OptionHandler returned parse error!\n");
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
return;
|
return;
|
||||||
@@ -1345,6 +1563,7 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
if(result != B_OK) {
|
if(result != B_OK) {
|
||||||
// the request contains a value that has been sent more than
|
// the request contains a value that has been sent more than
|
||||||
// once or the value is corrupted
|
// once or the value is corrupted
|
||||||
|
printf("PPPSM::RCREvent(): OptionHandler returned append error!\n");
|
||||||
m_freem(packet);
|
m_freem(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
return;
|
return;
|
||||||
@@ -1354,9 +1573,9 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(nak.CountItems() > 0)
|
if(nak.CountItems() > 0)
|
||||||
RCRBadEvent(nak.ToMbuf(LCP().AdditionalOverhead()), NULL);
|
RCRBadEvent(nak.ToMbuf(Interface().MRU(), LCP().AdditionalOverhead()), NULL);
|
||||||
else if(reject.CountItems() > 0)
|
else if(reject.CountItems() > 0)
|
||||||
RCRBadEvent(NULL, reject.ToMbuf(LCP().AdditionalOverhead()));
|
RCRBadEvent(NULL, reject.ToMbuf(Interface().MRU(), LCP().AdditionalOverhead()));
|
||||||
else
|
else
|
||||||
RCRGoodEvent(packet);
|
RCRGoodEvent(packet);
|
||||||
}
|
}
|
||||||
@@ -1368,6 +1587,11 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
PPPStateMachine::RXJEvent(struct mbuf *packet)
|
PPPStateMachine::RXJEvent(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: RXJEvent() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
|
ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
|
||||||
|
|
||||||
if(reject->code == PPP_CODE_REJECT) {
|
if(reject->code == PPP_CODE_REJECT) {
|
||||||
@@ -1433,12 +1657,19 @@ PPPStateMachine::IllegalEvent(ppp_event event)
|
|||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
// update error statistics
|
// update error statistics
|
||||||
|
printf("PPPSM: IllegalEvent(event=%d) state=%d phase=%d\n",
|
||||||
|
event, State(), Phase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PPPStateMachine::ThisLayerUp()
|
PPPStateMachine::ThisLayerUp()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: ThisLayerUp() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
// We begin with authentication phase and wait until each phase is done.
|
// We begin with authentication phase and wait until each phase is done.
|
||||||
@@ -1459,6 +1690,11 @@ PPPStateMachine::ThisLayerUp()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::ThisLayerDown()
|
PPPStateMachine::ThisLayerDown()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: ThisLayerDown() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
// PPPProtocol::Down() should block if needed.
|
// PPPProtocol::Down() should block if needed.
|
||||||
DownProtocols();
|
DownProtocols();
|
||||||
}
|
}
|
||||||
@@ -1467,6 +1703,11 @@ PPPStateMachine::ThisLayerDown()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::ThisLayerStarted()
|
PPPStateMachine::ThisLayerStarted()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: ThisLayerStarted() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(Interface().Device() && !Interface().Device()->Up())
|
if(Interface().Device() && !Interface().Device()->Up())
|
||||||
Interface().Device()->UpFailedEvent();
|
Interface().Device()->UpFailedEvent();
|
||||||
}
|
}
|
||||||
@@ -1475,6 +1716,11 @@ PPPStateMachine::ThisLayerStarted()
|
|||||||
void
|
void
|
||||||
PPPStateMachine::ThisLayerFinished()
|
PPPStateMachine::ThisLayerFinished()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: ThisLayerFinished() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(Interface().Device())
|
if(Interface().Device())
|
||||||
Interface().Device()->Down();
|
Interface().Device()->Down();
|
||||||
}
|
}
|
||||||
@@ -1507,7 +1753,15 @@ PPPStateMachine::ZeroRestartCount()
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::SendConfigureRequest()
|
PPPStateMachine::SendConfigureRequest()
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: SendConfigureRequest() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LockerHelper locker(fLock);
|
||||||
--fRequestCounter;
|
--fRequestCounter;
|
||||||
|
fNextTimeout = system_time() + PPP_STATE_MACHINE_TIMEOUT;
|
||||||
|
locker.UnlockNow();
|
||||||
|
|
||||||
PPPConfigurePacket request(PPP_CONFIGURE_REQUEST);
|
PPPConfigurePacket request(PPP_CONFIGURE_REQUEST);
|
||||||
request.SetID(NextID());
|
request.SetID(NextID());
|
||||||
@@ -1521,13 +1775,19 @@ PPPStateMachine::SendConfigureRequest()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LCP().Send(request.ToMbuf(LCP().AdditionalOverhead())) == B_OK;
|
return LCP().Send(request.ToMbuf(Interface().MRU(),
|
||||||
|
LCP().AdditionalOverhead())) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PPPStateMachine::SendConfigureAck(struct mbuf *packet)
|
PPPStateMachine::SendConfigureAck(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: SendConfigureAck() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!packet)
|
if(!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1550,6 +1810,11 @@ PPPStateMachine::SendConfigureAck(struct mbuf *packet)
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::SendConfigureNak(struct mbuf *packet)
|
PPPStateMachine::SendConfigureNak(struct mbuf *packet)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: SendConfigureNak() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!packet)
|
if(!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1569,29 +1834,42 @@ PPPStateMachine::SendConfigureNak(struct mbuf *packet)
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::SendTerminateRequest()
|
PPPStateMachine::SendTerminateRequest()
|
||||||
{
|
{
|
||||||
struct mbuf *m = m_gethdr(MT_DATA);
|
#if DEBUG
|
||||||
if(!m)
|
printf("PPPSM: SendTerminateRequest() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LockerHelper locker(fLock);
|
||||||
|
--fTerminateCounter;
|
||||||
|
fNextTimeout = system_time() + PPP_STATE_MACHINE_TIMEOUT;
|
||||||
|
locker.UnlockNow();
|
||||||
|
|
||||||
|
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||||
|
if(!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
--fTerminateCounter;
|
packet->m_pkthdr.len = packet->m_len = 4;
|
||||||
|
|
||||||
m->m_len = 4;
|
|
||||||
|
|
||||||
// reserve some space for other protocols
|
// reserve some space for other protocols
|
||||||
m->m_data += LCP().AdditionalOverhead();
|
packet->m_data += LCP().AdditionalOverhead();
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(m, ppp_lcp_packet*);
|
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
||||||
request->code = PPP_TERMINATE_REQUEST;
|
request->code = PPP_TERMINATE_REQUEST;
|
||||||
request->id = fTerminateID = NextID();
|
request->id = fTerminateID = NextID();
|
||||||
request->length = htons(4);
|
request->length = htons(4);
|
||||||
|
|
||||||
return LCP().Send(m) == B_OK;
|
return LCP().Send(packet) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
|
PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: SendTerminateAck() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
struct mbuf *reply = request;
|
struct mbuf *reply = request;
|
||||||
|
|
||||||
ppp_lcp_packet *ack;
|
ppp_lcp_packet *ack;
|
||||||
@@ -1602,7 +1880,7 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
reply->m_data += LCP().AdditionalOverhead();
|
reply->m_data += LCP().AdditionalOverhead();
|
||||||
reply->m_len = 4;
|
reply->m_pkthdr.len = reply->m_len = 4;
|
||||||
|
|
||||||
ack = mtod(reply, ppp_lcp_packet*);
|
ack = mtod(reply, ppp_lcp_packet*);
|
||||||
ack->id = NextID();
|
ack->id = NextID();
|
||||||
@@ -1619,6 +1897,11 @@ PPPStateMachine::SendTerminateAck(struct mbuf *request = NULL)
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code)
|
PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: SendCodeReject(protocolNumber=%d;code=%d) state=%d phase=%d\n",
|
||||||
|
protocolNumber, code, State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!packet)
|
if(!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1662,6 +1945,11 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint
|
|||||||
bool
|
bool
|
||||||
PPPStateMachine::SendEchoReply(struct mbuf *request)
|
PPPStateMachine::SendEchoReply(struct mbuf *request)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
printf("PPPSM: SendEchoReply() state=%d phase=%d\n",
|
||||||
|
State(), Phase());
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!request)
|
if(!request)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1671,7 +1959,6 @@ PPPStateMachine::SendEchoReply(struct mbuf *request)
|
|||||||
|
|
||||||
if(request->m_flags & M_PKTHDR)
|
if(request->m_flags & M_PKTHDR)
|
||||||
request->m_pkthdr.len = 8;
|
request->m_pkthdr.len = 8;
|
||||||
|
|
||||||
request->m_len = 8;
|
request->m_len = 8;
|
||||||
|
|
||||||
memcpy(reply->data, &fMagicNumber, sizeof(fMagicNumber));
|
memcpy(reply->data, &fMagicNumber, sizeof(fMagicNumber));
|
||||||
|
|||||||
@@ -34,9 +34,11 @@ status_t
|
|||||||
send_data_with_timeout(thread_id thread, int32 code, void *buffer,
|
send_data_with_timeout(thread_id thread, int32 code, void *buffer,
|
||||||
size_t buffer_size, uint32 timeout)
|
size_t buffer_size, uint32 timeout)
|
||||||
{
|
{
|
||||||
for(uint32 tries = 0; tries < timeout; tries++) {
|
for(uint32 tries = 0; tries < timeout; tries += 5) {
|
||||||
if(has_data(thread))
|
if(has_data(thread))
|
||||||
snooze(1000);
|
snooze(5000);
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!has_data(thread))
|
if(!has_data(thread))
|
||||||
@@ -50,11 +52,11 @@ status_t
|
|||||||
receive_data_with_timeout(thread_id *sender, int32 *code, void *buffer,
|
receive_data_with_timeout(thread_id *sender, int32 *code, void *buffer,
|
||||||
size_t buffer_size, uint32 timeout)
|
size_t buffer_size, uint32 timeout)
|
||||||
{
|
{
|
||||||
for(uint32 tries = 0; tries < timeout; tries++) {
|
for(uint32 tries = 0; tries < timeout; tries += 5) {
|
||||||
if(!has_data(find_thread(NULL))) {
|
if(!has_data(find_thread(NULL)))
|
||||||
snooze(1000);
|
snooze(5000);
|
||||||
continue;
|
else
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(has_data(find_thread(NULL))) {
|
if(has_data(find_thread(NULL))) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
|
||||||
#define AUTHENTICATION_TYPE 0x3
|
#define AUTHENTICATION_TYPE 0x3
|
||||||
#define AUTHENTICATOR_TYPE_STRING "Authenticator"
|
#define AUTHENTICATOR_TYPE_STRING "Authenticator"
|
||||||
|
|
||||||
@@ -159,14 +160,13 @@ _PPPAuthenticationHandler::ParseAck(const PPPConfigurePacket& ack)
|
|||||||
authentication_item *item =
|
authentication_item *item =
|
||||||
(authentication_item*) ack.ItemWithType(AUTHENTICATION_TYPE);
|
(authentication_item*) ack.ItemWithType(AUTHENTICATION_TYPE);
|
||||||
|
|
||||||
if(!fPeerAuthenticator)
|
|
||||||
return B_ERROR;
|
|
||||||
// could not find the authenticator
|
|
||||||
|
|
||||||
if(!item) {
|
if(!item) {
|
||||||
if(fPeerAuthenticator)
|
if(fPeerAuthenticator)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
// the ack does not contain our request
|
// the ack does not contain our request
|
||||||
|
else
|
||||||
|
return B_OK;
|
||||||
|
// no authentication needed
|
||||||
} else if(!fPeerAuthenticator
|
} else if(!fPeerAuthenticator
|
||||||
|| ntohs(item->protocolNumber) != fPeerAuthenticator->ProtocolNumber())
|
|| ntohs(item->protocolNumber) != fPeerAuthenticator->ProtocolNumber())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
|
||||||
#define MRU_TYPE 0x1
|
#define MRU_TYPE 0x1
|
||||||
|
|
||||||
typedef struct mru_item {
|
typedef struct mru_item {
|
||||||
@@ -115,7 +116,7 @@ ParseRequestedItem(mru_item *item, PPPInterface& interface)
|
|||||||
if(item) {
|
if(item) {
|
||||||
if(item->length != 4)
|
if(item->length != 4)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
// the request had a corrupted item
|
// the request has a corrupted item
|
||||||
|
|
||||||
MRU = ntohs(item->MRU);
|
MRU = ntohs(item->MRU);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <KPPPConfigurePacket.h>
|
#include <KPPPConfigurePacket.h>
|
||||||
|
|
||||||
|
|
||||||
#define PFC_TYPE 0x7
|
#define PFC_TYPE 0x7
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class PPPConfigurePacket {
|
|||||||
ppp_configure_item *ItemAt(int32 index) const;
|
ppp_configure_item *ItemAt(int32 index) const;
|
||||||
ppp_configure_item *ItemWithType(uint8 type) const;
|
ppp_configure_item *ItemWithType(uint8 type) const;
|
||||||
|
|
||||||
struct mbuf *ToMbuf(uint32 reserve = 0);
|
struct mbuf *ToMbuf(uint32 MRU, uint32 reserve = 0);
|
||||||
// the user is responsible for freeing the mbuf
|
// the user is responsible for freeing the mbuf
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class PPPDevice : public PPPLayer {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// PPPDevice must be subclassed
|
// PPPDevice must be subclassed
|
||||||
PPPDevice(const char *name, PPPInterface& interface,
|
PPPDevice(const char *name, uint32 overhead, PPPInterface& interface,
|
||||||
driver_parameter *settings);
|
driver_parameter *settings);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ struct ppp_module_info;
|
|||||||
class PPPInterface : public PPPLayer {
|
class PPPInterface : public PPPLayer {
|
||||||
friend class PPPStateMachine;
|
friend class PPPStateMachine;
|
||||||
friend class PPPManager;
|
friend class PPPManager;
|
||||||
|
friend class PPPInterfaceAccess;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// copies are not allowed!
|
// copies are not allowed!
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
class PPPLayer {
|
class PPPLayer {
|
||||||
protected:
|
protected:
|
||||||
// PPPLayer must be subclassed
|
// PPPLayer must be subclassed
|
||||||
PPPLayer(const char *name, ppp_level level);
|
PPPLayer(const char *name, ppp_level level, uint32 overhead);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~PPPLayer();
|
virtual ~PPPLayer();
|
||||||
@@ -26,6 +26,8 @@ class PPPLayer {
|
|||||||
ppp_level Level() const
|
ppp_level Level() const
|
||||||
{ return fLevel; }
|
{ return fLevel; }
|
||||||
// should be PPP_PROTOCOL_LEVEL if not encapsulator
|
// should be PPP_PROTOCOL_LEVEL if not encapsulator
|
||||||
|
uint32 Overhead() const
|
||||||
|
{ return fOverhead; }
|
||||||
|
|
||||||
void SetNext(PPPLayer *next)
|
void SetNext(PPPLayer *next)
|
||||||
{ fNext = next; }
|
{ fNext = next; }
|
||||||
@@ -47,6 +49,7 @@ class PPPLayer {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
status_t fInitStatus;
|
status_t fInitStatus;
|
||||||
|
uint32 fOverhead;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *fName;
|
char *fName;
|
||||||
|
|||||||
@@ -35,10 +35,6 @@ class PPPProtocol : public PPPLayer {
|
|||||||
ppp_phase ActivationPhase() const
|
ppp_phase ActivationPhase() const
|
||||||
{ return fActivationPhase; }
|
{ return fActivationPhase; }
|
||||||
|
|
||||||
uint32 Overhead() const
|
|
||||||
{ return fOverhead; }
|
|
||||||
// only useful for encapsulation protocols
|
|
||||||
|
|
||||||
uint16 ProtocolNumber() const
|
uint16 ProtocolNumber() const
|
||||||
{ return fProtocolNumber; }
|
{ return fProtocolNumber; }
|
||||||
int32 AddressFamily() const
|
int32 AddressFamily() const
|
||||||
@@ -103,7 +99,6 @@ class PPPProtocol : public PPPLayer {
|
|||||||
void DownEvent();
|
void DownEvent();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32 fOverhead;
|
|
||||||
ppp_side fSide;
|
ppp_side fSide;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
|
|
||||||
#define PPP_REPORT_TIMEOUT 10
|
#define PPP_REPORT_TIMEOUT 100
|
||||||
|
|
||||||
#define PPP_REPORT_DATA_LIMIT 128
|
#define PPP_REPORT_DATA_LIMIT 128
|
||||||
// how much optional data can be added to the report
|
// how much optional data can be added to the report
|
||||||
|
|||||||
Reference in New Issue
Block a user