PPP: Port to the new stack.
Signed-off-by: Augustin Cavalier <[email protected]> This is a squash of the 42 commits by @mshlyn, as I couldn't find a way to break them into logical chunks. I did not include these in the build, as it appears that they only partially work anyway, and much more cleanup is still needed. However, this is a huge improvement on what was in the tree before, which looked horrendous and didn't even compile (as it was designed for the old stack). Mostly fixes #812.
This commit is contained in:
committed by
Augustin Cavalier
parent
7121057cb7
commit
e3724c38cb
@@ -134,7 +134,7 @@ SYSTEM_NETWORK_DATALINK_PROTOCOLS =
|
|||||||
loopback_frame
|
loopback_frame
|
||||||
;
|
;
|
||||||
|
|
||||||
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe ;
|
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe KPPPManager ;
|
||||||
|
|
||||||
SYSTEM_NETWORK_PROTOCOLS =
|
SYSTEM_NETWORK_PROTOCOLS =
|
||||||
icmp icmp6 ipv4 ipv6
|
icmp icmp6 ipv4 ipv6
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ AddFilesToPackage add-ons kernel network : dns_resolver ;
|
|||||||
AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ;
|
AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ;
|
||||||
AddFilesToPackage add-ons kernel network datalink_protocols
|
AddFilesToPackage add-ons kernel network datalink_protocols
|
||||||
: $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ;
|
: $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ;
|
||||||
AddFilesToPackage add-ons kernel network ppp: $(SYSTEM_NETWORK_PPP) ;
|
AddFilesToPackage add-ons kernel network ppp : $(SYSTEM_NETWORK_PPP) ;
|
||||||
AddFilesToPackage add-ons kernel network protocols
|
AddFilesToPackage add-ons kernel network protocols
|
||||||
: $(SYSTEM_NETWORK_PROTOCOLS) ;
|
: $(SYSTEM_NETWORK_PROTOCOLS) ;
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ AddFilesToPackage add-ons kernel network : dns_resolver ;
|
|||||||
AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ;
|
AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ;
|
||||||
AddFilesToPackage add-ons kernel network datalink_protocols
|
AddFilesToPackage add-ons kernel network datalink_protocols
|
||||||
: $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ;
|
: $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ;
|
||||||
AddFilesToPackage add-ons kernel network ppp: $(SYSTEM_NETWORK_PPP) ;
|
AddFilesToPackage add-ons kernel network ppp : $(SYSTEM_NETWORK_PPP) ;
|
||||||
AddFilesToPackage add-ons kernel network protocols
|
AddFilesToPackage add-ons kernel network protocols
|
||||||
: $(SYSTEM_NETWORK_PROTOCOLS) ;
|
: $(SYSTEM_NETWORK_PROTOCOLS) ;
|
||||||
|
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ SubInclude HAIKU_TOP src add-ons kernel network dns_resolver ;
|
|||||||
SubInclude HAIKU_TOP src add-ons kernel network notifications ;
|
SubInclude HAIKU_TOP src add-ons kernel network notifications ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network protocols ;
|
SubInclude HAIKU_TOP src add-ons kernel network protocols ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network stack ;
|
SubInclude HAIKU_TOP src add-ons kernel network stack ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel network ppp ;
|
SubDir HAIKU_TOP src add-ons kernel network ppp ;
|
||||||
|
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
|
# SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp pap ;
|
SubInclude HAIKU_TOP src add-ons kernel network ppp pap ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
SubInclude HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp shared ;
|
SubInclude HAIKU_TOP src add-ons kernel network ppp shared ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
|
||||||
|
|||||||
@@ -1,41 +1,51 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
SubDir HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
if $(TARGET_PLATFORM) != haiku {
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||||
# We need the public network headers also when not compiling for Haiku.
|
# Needed for the atomic_add64() prototype.
|
||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# for kernel_cpp.h and BLocker
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
# We need the public network headers also when not compiling for Haiku.
|
||||||
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
|
|
||||||
|
UsePrivateHeaders libroot net ;
|
||||||
UsePrivateHeaders [ FDirName kernel ] ;
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
libkernelppp headers ] : true ;
|
libkernelppp headers ] : true ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp pppoe
|
||||||
|
] : true ;
|
||||||
{
|
|
||||||
SubDirC++Flags -fno-rtti ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
KernelAddon ipcp :
|
KernelAddon ipcp :
|
||||||
# imported from libnet
|
atomic.S
|
||||||
|
kernel_cpp.cpp
|
||||||
|
|
||||||
|
# imported from kernel util
|
||||||
inet_addr.c
|
inet_addr.c
|
||||||
|
|
||||||
ipcp.cpp
|
ipcp.cpp
|
||||||
Protocol.cpp
|
Protocol.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
SEARCH on [ FGristFiles inet_addr.c ]
|
SEARCH on [ FGristFiles inet_addr.c ]
|
||||||
= [ FDirName $(HAIKU_TOP) src kits network compat libnet ] ;
|
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||||
|
|
||||||
|
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||||
|
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||||
|
SEARCH on [ FGristFiles atomic.S ]
|
||||||
|
= [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
|
||||||
|
|
||||||
LinkAgainst ipcp : libkernelppp.a ;
|
LinkAgainst ipcp : libkernelppp.a ;
|
||||||
|
|
||||||
# Installation
|
|
||||||
HaikuInstall install-networking
|
HaikuInstall install-networking
|
||||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
: /boot/home/config/add-ons/kernel/network/ppp
|
||||||
: ipcp ;
|
: ipcp ;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,9 +9,11 @@
|
|||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
|
|
||||||
#include <KPPPProtocol.h>
|
#include <KPPPProtocol.h>
|
||||||
#include <Locker.h>
|
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <net_datalink.h>
|
||||||
|
#include <net_datalink_protocol.h>
|
||||||
|
#include <net/route.h>
|
||||||
|
|
||||||
|
|
||||||
#define IPCP_PROTOCOL 0x8021
|
#define IPCP_PROTOCOL 0x8021
|
||||||
@@ -60,46 +62,46 @@ class IPCP : public KPPPProtocol {
|
|||||||
public:
|
public:
|
||||||
IPCP(KPPPInterface& interface, driver_parameter *settings);
|
IPCP(KPPPInterface& interface, driver_parameter *settings);
|
||||||
virtual ~IPCP();
|
virtual ~IPCP();
|
||||||
|
|
||||||
virtual void Uninit();
|
virtual void Uninit();
|
||||||
|
|
||||||
ppp_state State() const
|
ppp_state State() const
|
||||||
{ return fState; }
|
{ return fState; }
|
||||||
|
|
||||||
virtual status_t StackControl(uint32 op, void *data);
|
virtual status_t StackControl(uint32 op, void *data);
|
||||||
|
|
||||||
virtual bool Up();
|
virtual bool Up();
|
||||||
virtual bool Down();
|
virtual bool Down();
|
||||||
|
|
||||||
virtual status_t Send(struct mbuf *packet,
|
virtual status_t Send(net_buffer *packet,
|
||||||
uint16 protocolNumber = IPCP_PROTOCOL);
|
uint16 protocolNumber = IPCP_PROTOCOL);
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||||
status_t ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber);
|
status_t ReceiveIPPacket(net_buffer *packet, uint16 protocolNumber);
|
||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ParseSideRequests(const driver_parameter *requests, ppp_side side);
|
bool ParseSideRequests(const driver_parameter *requests, ppp_side side);
|
||||||
void UpdateAddresses();
|
void UpdateAddresses();
|
||||||
void RemoveRoutes();
|
void RemoveRoutes();
|
||||||
|
|
||||||
// for state machine
|
// for state machine
|
||||||
void NewState(ppp_state next);
|
void NewState(ppp_state next);
|
||||||
uint8 NextID();
|
uint8 NextID();
|
||||||
// return the next id for IPCP packets
|
// return the next id for IPCP packets
|
||||||
|
|
||||||
// events
|
// events
|
||||||
void TOGoodEvent();
|
void TOGoodEvent();
|
||||||
void TOBadEvent();
|
void TOBadEvent();
|
||||||
void RCREvent(struct mbuf *packet);
|
void RCREvent(net_buffer *packet);
|
||||||
void RCRGoodEvent(struct mbuf *packet);
|
void RCRGoodEvent(net_buffer *packet);
|
||||||
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject);
|
void RCRBadEvent(net_buffer *nak, net_buffer *reject);
|
||||||
void RCAEvent(struct mbuf *packet);
|
void RCAEvent(net_buffer *packet);
|
||||||
void RCNEvent(struct mbuf *packet);
|
void RCNEvent(net_buffer *packet);
|
||||||
void RTREvent(struct mbuf *packet);
|
void RTREvent(net_buffer *packet);
|
||||||
void RTAEvent(struct mbuf *packet);
|
void RTAEvent(net_buffer *packet);
|
||||||
void RUCEvent(struct mbuf *packet);
|
void RUCEvent(net_buffer *packet);
|
||||||
void RXJBadEvent(struct mbuf *packet);
|
void RXJBadEvent(net_buffer *packet);
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
void IllegalEvent(ppp_event event);
|
void IllegalEvent(ppp_event event);
|
||||||
void ReportUpFailedEvent();
|
void ReportUpFailedEvent();
|
||||||
@@ -108,27 +110,27 @@ class IPCP : public KPPPProtocol {
|
|||||||
void InitializeRestartCount();
|
void InitializeRestartCount();
|
||||||
void ResetRestartCount();
|
void ResetRestartCount();
|
||||||
bool SendConfigureRequest();
|
bool SendConfigureRequest();
|
||||||
bool SendConfigureAck(struct mbuf *packet);
|
bool SendConfigureAck(net_buffer *packet);
|
||||||
bool SendConfigureNak(struct mbuf *packet);
|
bool SendConfigureNak(net_buffer *packet);
|
||||||
bool SendTerminateRequest();
|
bool SendTerminateRequest();
|
||||||
bool SendTerminateAck(struct mbuf *request = NULL);
|
bool SendTerminateAck(net_buffer *request = NULL);
|
||||||
bool SendCodeReject(struct mbuf *packet);
|
bool SendCodeReject(net_buffer *packet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ipcp_configuration fLocalConfiguration, fPeerConfiguration;
|
ipcp_configuration fLocalConfiguration, fPeerConfiguration;
|
||||||
ipcp_requests fLocalRequests, fPeerRequests;
|
ipcp_requests fLocalRequests, fPeerRequests;
|
||||||
|
|
||||||
// default route
|
// default route
|
||||||
struct sockaddr_in fGateway;
|
struct sockaddr_in fGateway;
|
||||||
rtentry *fDefaultRoute;
|
net_route *fDefaultRoute;
|
||||||
|
|
||||||
// used for local requests
|
// used for local requests
|
||||||
bool fRequestPrimaryDNS, fRequestSecondaryDNS;
|
bool fRequestPrimaryDNS, fRequestSecondaryDNS;
|
||||||
|
|
||||||
// for state machine
|
// for state machine
|
||||||
ppp_state fState;
|
ppp_state fState;
|
||||||
vint32 fID;
|
int32 fID;
|
||||||
|
|
||||||
// counters and timers
|
// counters and timers
|
||||||
int32 fMaxRequest, fMaxTerminate, fMaxNak;
|
int32 fMaxRequest, fMaxTerminate, fMaxNak;
|
||||||
int32 fRequestCounter, fTerminateCounter, fNakCounter;
|
int32 fRequestCounter, fTerminateCounter, fNakCounter;
|
||||||
|
|||||||
@@ -5,21 +5,24 @@
|
|||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
#include <net_module.h>
|
|
||||||
|
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
|
#include <KPPPDefs.h>
|
||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
#include <KPPPModule.h>
|
#include <KPPPModule.h>
|
||||||
|
|
||||||
#include "Protocol.h"
|
#include "Protocol.h"
|
||||||
|
|
||||||
|
#define IPCP_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/ipcp"
|
||||||
|
|
||||||
#define IPCP_MODULE_NAME NETWORK_MODULES_ROOT "ppp/ipcp"
|
|
||||||
|
|
||||||
struct protosw *gProto[IPPROTO_MAX];
|
|
||||||
struct core_module_info *core = NULL;
|
|
||||||
status_t std_ops(int32 op, ...);
|
status_t std_ops(int32 op, ...);
|
||||||
|
|
||||||
|
net_stack_module_info *gStackModule = NULL;
|
||||||
|
net_buffer_module_info *gBufferModule = NULL;
|
||||||
|
|
||||||
|
|
||||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
// TODO: Remove isascii() (needed for inet_aton()) when our kernel is finished!
|
// TODO: Remove isascii() (needed for inet_aton()) when our kernel is finished!
|
||||||
@@ -28,7 +31,7 @@ extern "C"
|
|||||||
int
|
int
|
||||||
isascii(char c)
|
isascii(char c)
|
||||||
{
|
{
|
||||||
return c & ~0x7f == 0; // If c is a 7 bit value.
|
return ((c & (~0x7f)) == 0); // If c is a 7 bit value.
|
||||||
}
|
}
|
||||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
|
|
||||||
@@ -38,22 +41,22 @@ bool
|
|||||||
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
||||||
driver_parameter *settings, ppp_module_key_type type)
|
driver_parameter *settings, ppp_module_key_type type)
|
||||||
{
|
{
|
||||||
if(type != PPP_PROTOCOL_KEY_TYPE)
|
if (type != PPP_PROTOCOL_KEY_TYPE)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
IPCP *ipcp;
|
IPCP *ipcp;
|
||||||
bool success;
|
bool success;
|
||||||
if(subInterface) {
|
if (subInterface) {
|
||||||
ipcp = new IPCP(*subInterface, settings);
|
ipcp = new IPCP(*subInterface, settings);
|
||||||
success = subInterface->AddProtocol(ipcp);
|
success = subInterface->AddProtocol(ipcp);
|
||||||
} else {
|
} else {
|
||||||
ipcp = new IPCP(mainInterface, settings);
|
ipcp = new IPCP(mainInterface, settings);
|
||||||
success = mainInterface.AddProtocol(ipcp);
|
success = mainInterface.AddProtocol(ipcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("IPCP: add_to(): %s\n",
|
TRACE("IPCP: add_to(): %s\n",
|
||||||
success && ipcp && ipcp->InitCheck() == B_OK ? "OK" : "ERROR");
|
success && ipcp && ipcp->InitCheck() == B_OK ? "OK" : "ERROR");
|
||||||
|
|
||||||
return success && ipcp && ipcp->InitCheck() == B_OK;
|
return success && ipcp && ipcp->InitCheck() == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,24 +74,30 @@ static ppp_module_info ipcp_module = {
|
|||||||
|
|
||||||
_EXPORT
|
_EXPORT
|
||||||
status_t
|
status_t
|
||||||
std_ops(int32 op, ...)
|
std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch (op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT:
|
||||||
if(get_module(NET_CORE_MODULE_NAME, (module_info**) &core) != B_OK)
|
if (get_module(NET_STACK_MODULE_NAME,
|
||||||
|
(module_info**) &gStackModule) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
memset(gProto, 0, sizeof(struct protosw*) * IPPROTO_MAX);
|
if (get_module(NET_BUFFER_MODULE_NAME,
|
||||||
add_protosw(gProto, NET_LAYER1);
|
(module_info **)&gBufferModule) != B_OK) {
|
||||||
return B_OK;
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
put_module(NET_CORE_MODULE_NAME);
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
break;
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel network ppp pap ;
|
SubDir HAIKU_TOP src add-ons kernel network ppp pap ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
if $(TARGET_PLATFORM) != haiku {
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
# for kernel_cpp.h and BLocker
|
UsePrivateKernelHeaders ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
UsePrivateHeaders [ FDirName kernel ] ;
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
libkernelppp headers ] : true ;
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
SubDirC++Flags -fno-rtti ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
KernelAddon pap :
|
KernelAddon pap :
|
||||||
pap.cpp
|
pap.cpp
|
||||||
Protocol.cpp
|
Protocol.cpp
|
||||||
@@ -31,5 +25,5 @@ LinkAgainst pap : libkernelppp.a ;
|
|||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
HaikuInstall install-networking
|
HaikuInstall install-networking
|
||||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
: /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||||
: pap ;
|
: pap ;
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
static const bigtime_t kPAPTimeout = 3000000;
|
static const bigtime_t kPAPTimeout = 3000000;
|
||||||
// 3 seconds
|
// 3 seconds
|
||||||
@@ -34,20 +34,28 @@ PAPHandler::PAPHandler(PAP& owner, KPPPInterface& interface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PAPHandler::SendingAck(const KPPPConfigurePacket& ack)
|
||||||
|
{
|
||||||
|
TRACE("%s::%s: We should activate PAP Protocol here\n", __FILE__, __func__);
|
||||||
|
return KPPPOptionHandler::SendingAck(ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PAPHandler::AddToRequest(KPPPConfigurePacket& request)
|
PAPHandler::AddToRequest(KPPPConfigurePacket& request)
|
||||||
{
|
{
|
||||||
// only local authenticators send requests to peer
|
// only local authenticators send requests to peer
|
||||||
if(Owner().Side() != PPP_PEER_SIDE)
|
if (Owner().Side() != PPP_PEER_SIDE)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
authentication_item item;
|
authentication_item item;
|
||||||
item.type = kAuthenticationType;
|
item.type = kAuthenticationType;
|
||||||
item.length = sizeof(item);
|
item.length = sizeof(item);
|
||||||
item.protocolNumber = htons(PAP_PROTOCOL);
|
item.protocolNumber = htons(PAP_PROTOCOL);
|
||||||
|
|
||||||
request.AddItem((ppp_configure_item*) &item);
|
request.AddItem((ppp_configure_item*) &item);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,15 +65,15 @@ PAPHandler::ParseRequest(const KPPPConfigurePacket& request,
|
|||||||
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject)
|
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject)
|
||||||
{
|
{
|
||||||
// only local authenticators handle requests from peer
|
// only local authenticators handle requests from peer
|
||||||
if(Owner().Side() != PPP_LOCAL_SIDE)
|
if (Owner().Side() != PPP_LOCAL_SIDE)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// we merely check if the values are correct
|
// we merely check if the values are correct
|
||||||
authentication_item *item = (authentication_item*) request.ItemAt(index);
|
authentication_item *item = (authentication_item*) request.ItemAt(index);
|
||||||
if(item->type != kAuthenticationType
|
if (item->type != kAuthenticationType
|
||||||
|| item->length != 4 || ntohs(item->protocolNumber) != PAP_PROTOCOL)
|
|| item->length != 4 || ntohs(item->protocolNumber) != PAP_PROTOCOL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +100,9 @@ PAP::~PAP()
|
|||||||
status_t
|
status_t
|
||||||
PAP::InitCheck() const
|
PAP::InitCheck() const
|
||||||
{
|
{
|
||||||
if(Side() != PPP_LOCAL_SIDE && Side() != PPP_PEER_SIDE)
|
if (Side() != PPP_LOCAL_SIDE && Side() != PPP_PEER_SIDE)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
return KPPPProtocol::InitCheck();
|
return KPPPProtocol::InitCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,14 +111,14 @@ bool
|
|||||||
PAP::Up()
|
PAP::Up()
|
||||||
{
|
{
|
||||||
TRACE("PAP: Up() state=%d\n", State());
|
TRACE("PAP: Up() state=%d\n", State());
|
||||||
|
|
||||||
switch(State()) {
|
switch (State()) {
|
||||||
case INITIAL:
|
case INITIAL:
|
||||||
if(Side() == PPP_LOCAL_SIDE) {
|
if (Side() == PPP_LOCAL_SIDE) {
|
||||||
NewState(REQ_SENT);
|
NewState(REQ_SENT);
|
||||||
InitializeRestartCount();
|
InitializeRestartCount();
|
||||||
SendRequest();
|
SendRequest();
|
||||||
} else if(Side() == PPP_PEER_SIDE) {
|
} else if (Side() == PPP_PEER_SIDE) {
|
||||||
NewState(WAITING_FOR_REQ);
|
NewState(WAITING_FOR_REQ);
|
||||||
InitializeRestartCount();
|
InitializeRestartCount();
|
||||||
fNextTimeout = system_time() + kPAPTimeout;
|
fNextTimeout = system_time() + kPAPTimeout;
|
||||||
@@ -119,11 +127,11 @@ PAP::Up()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,8 +140,8 @@ bool
|
|||||||
PAP::Down()
|
PAP::Down()
|
||||||
{
|
{
|
||||||
TRACE("PAP: Down() state=%d\n", State());
|
TRACE("PAP: Down() state=%d\n", State());
|
||||||
|
|
||||||
switch(Interface().Phase()) {
|
switch (Interface().Phase()) {
|
||||||
case PPP_DOWN_PHASE:
|
case PPP_DOWN_PHASE:
|
||||||
// interface finished terminating
|
// interface finished terminating
|
||||||
case PPP_ESTABLISHED_PHASE:
|
case PPP_ESTABLISHED_PHASE:
|
||||||
@@ -141,82 +149,83 @@ PAP::Down()
|
|||||||
NewState(INITIAL);
|
NewState(INITIAL);
|
||||||
DownEvent();
|
DownEvent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* case PPP_TERMINATION_PHASE:
|
/* case PPP_TERMINATION_PHASE:
|
||||||
// interface is terminating
|
// interface is terminating
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_ESTABLISHMENT_PHASE:
|
case PPP_ESTABLISHMENT_PHASE:
|
||||||
// interface is reconfiguring
|
// interface is reconfiguring
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PAP::Send(struct mbuf *packet, uint16 protocolNumber)
|
PAP::Send(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
// we do not encapsulate PAP packets
|
// we do not encapsulate PAP packets
|
||||||
m_freem(packet);
|
TRACE("PAP: we should not send packet!\n");
|
||||||
|
if (packet != NULL)
|
||||||
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PAP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
PAP::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
if(!packet)
|
if (!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if(protocolNumber != PAP_PROTOCOL)
|
if (protocolNumber != PAP_PROTOCOL)
|
||||||
return PPP_UNHANDLED;
|
return PPP_UNHANDLED;
|
||||||
|
|
||||||
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
ppp_lcp_packet &data = bufferheader.Data();
|
||||||
|
|
||||||
// check if the packet is meant for us:
|
// check if the packet is meant for us:
|
||||||
// only peer authenticators handle requests
|
// only peer authenticators handle requests
|
||||||
if(data->code == PPP_CONFIGURE_REQUEST && Side() != PPP_PEER_SIDE)
|
if (data.code == PPP_CONFIGURE_REQUEST && Side() != PPP_PEER_SIDE)
|
||||||
return PPP_UNHANDLED;
|
return PPP_UNHANDLED;
|
||||||
// only local authenticators handle acks and naks
|
// only local authenticators handle acks and naks
|
||||||
if((data->code == PPP_CONFIGURE_ACK || data->code == PPP_CONFIGURE_NAK)
|
if ((data.code == PPP_CONFIGURE_ACK || data.code == PPP_CONFIGURE_NAK)
|
||||||
&& Side() != PPP_LOCAL_SIDE)
|
&& Side() != PPP_LOCAL_SIDE)
|
||||||
return PPP_UNHANDLED;
|
return PPP_UNHANDLED;
|
||||||
|
|
||||||
// remove padding
|
// remove padding
|
||||||
int32 length = packet->m_len;
|
int32 length = packet->size;
|
||||||
if(packet->m_flags & M_PKTHDR)
|
length -= ntohs(data.length);
|
||||||
length = packet->m_pkthdr.len;
|
|
||||||
length -= ntohs(data->length);
|
if (ntohs(data.length) < 4)
|
||||||
if(length)
|
|
||||||
m_adj(packet, -length);
|
|
||||||
|
|
||||||
if(ntohs(data->length) < 4)
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// packet is freed by event methods
|
// packet is freed by event methods
|
||||||
// code values are the same as for LCP (but very reduced)
|
// code values are the same as for LCP (but very reduced)
|
||||||
switch(data->code) {
|
switch (data.code) {
|
||||||
case PPP_CONFIGURE_REQUEST:
|
case PPP_CONFIGURE_REQUEST:
|
||||||
RREvent(packet);
|
RREvent(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_CONFIGURE_ACK:
|
case PPP_CONFIGURE_ACK:
|
||||||
RAEvent(packet);
|
RAEvent(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_CONFIGURE_NAK:
|
case PPP_CONFIGURE_NAK:
|
||||||
RNEvent(packet);
|
RNEvent(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return PPP_UNHANDLED;
|
return PPP_UNHANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,19 +233,19 @@ PAP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
void
|
void
|
||||||
PAP::Pulse()
|
PAP::Pulse()
|
||||||
{
|
{
|
||||||
if(fNextTimeout == 0 || fNextTimeout > system_time())
|
if (fNextTimeout == 0 || fNextTimeout > system_time())
|
||||||
return;
|
return;
|
||||||
fNextTimeout = 0;
|
fNextTimeout = 0;
|
||||||
|
|
||||||
switch(State()) {
|
switch (State()) {
|
||||||
case REQ_SENT:
|
case REQ_SENT:
|
||||||
case WAITING_FOR_REQ:
|
case WAITING_FOR_REQ:
|
||||||
if(fRequestCounter <= 0)
|
if (fRequestCounter <= 0)
|
||||||
TOBadEvent();
|
TOBadEvent();
|
||||||
else
|
else
|
||||||
TOGoodEvent();
|
TOGoodEvent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -254,22 +263,22 @@ void
|
|||||||
PAP::NewState(pap_state next)
|
PAP::NewState(pap_state next)
|
||||||
{
|
{
|
||||||
TRACE("PAP: NewState(%d) state=%d\n", next, State());
|
TRACE("PAP: NewState(%d) state=%d\n", next, State());
|
||||||
|
|
||||||
// state changes
|
// state changes
|
||||||
if(State() == INITIAL && next != State()) {
|
if (State() == INITIAL && next != State()) {
|
||||||
if(Side() == PPP_LOCAL_SIDE)
|
if (Side() == PPP_LOCAL_SIDE)
|
||||||
Interface().StateMachine().LocalAuthenticationRequested();
|
Interface().StateMachine().LocalAuthenticationRequested();
|
||||||
else if(Side() == PPP_PEER_SIDE)
|
else if (Side() == PPP_PEER_SIDE)
|
||||||
Interface().StateMachine().PeerAuthenticationRequested();
|
Interface().StateMachine().PeerAuthenticationRequested();
|
||||||
|
|
||||||
UpStarted();
|
UpStarted();
|
||||||
} else if(State() == ACCEPTED && next != State())
|
} else if (State() == ACCEPTED && next != State())
|
||||||
DownStarted();
|
DownStarted();
|
||||||
|
|
||||||
// maybe we do not need the timer anymore
|
// maybe we do not need the timer anymore
|
||||||
if(next == INITIAL || next == ACCEPTED)
|
if (next == INITIAL || next == ACCEPTED)
|
||||||
fNextTimeout = 0;
|
fNextTimeout = 0;
|
||||||
|
|
||||||
fState = next;
|
fState = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,16 +287,16 @@ void
|
|||||||
PAP::TOGoodEvent()
|
PAP::TOGoodEvent()
|
||||||
{
|
{
|
||||||
TRACE("PAP: TOGoodEvent() state=%d\n", State());
|
TRACE("PAP: TOGoodEvent() state=%d\n", State());
|
||||||
|
|
||||||
switch(State()) {
|
switch (State()) {
|
||||||
case REQ_SENT:
|
case REQ_SENT:
|
||||||
SendRequest();
|
SendRequest();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAITING_FOR_REQ:
|
case WAITING_FOR_REQ:
|
||||||
fNextTimeout = system_time() + kPAPTimeout;
|
fNextTimeout = system_time() + kPAPTimeout;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -298,21 +307,21 @@ void
|
|||||||
PAP::TOBadEvent()
|
PAP::TOBadEvent()
|
||||||
{
|
{
|
||||||
TRACE("PAP: TOBadEvent() state=%d\n", State());
|
TRACE("PAP: TOBadEvent() state=%d\n", State());
|
||||||
|
|
||||||
switch(State()) {
|
switch (State()) {
|
||||||
case REQ_SENT:
|
case REQ_SENT:
|
||||||
case WAITING_FOR_REQ:
|
case WAITING_FOR_REQ:
|
||||||
NewState(INITIAL);
|
NewState(INITIAL);
|
||||||
if(State() == REQ_SENT)
|
if (State() == REQ_SENT)
|
||||||
Interface().StateMachine().LocalAuthenticationDenied(
|
Interface().StateMachine().LocalAuthenticationDenied(
|
||||||
Interface().Username());
|
Interface().Username());
|
||||||
else
|
else
|
||||||
Interface().StateMachine().PeerAuthenticationDenied(
|
Interface().StateMachine().PeerAuthenticationDenied(
|
||||||
Interface().Username());
|
Interface().Username());
|
||||||
|
|
||||||
UpFailedEvent();
|
UpFailedEvent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@@ -320,27 +329,30 @@ PAP::TOBadEvent()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PAP::RREvent(struct mbuf *packet)
|
PAP::RREvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("PAP: RREvent() state=%d\n", State());
|
TRACE("PAP: RREvent() state=%d\n", State());
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
int32 length = ntohs(request->length);
|
if (bufferheader.Status() != B_OK)
|
||||||
uint8 *data = request->data;
|
return;
|
||||||
|
ppp_lcp_packet &request = bufferheader.Data();
|
||||||
|
int32 length = ntohs(request.length);
|
||||||
|
uint8 *data = request.data;
|
||||||
uint8 *userLength = data;
|
uint8 *userLength = data;
|
||||||
uint8 *passwordLength = data + 1 + data[0];
|
uint8 *passwordLength = data + 1 + data[0];
|
||||||
|
|
||||||
// make sure the length values are all okay
|
// make sure the length values are all okay
|
||||||
if(6 + *userLength + *passwordLength > length) {
|
if (6 + *userLength + *passwordLength > length) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *peerUsername = (char*) userLength + 1,
|
char *peerUsername = (char*) userLength + 1,
|
||||||
*peerPassword = (char*) passwordLength + 1;
|
*peerPassword = (char*) passwordLength + 1;
|
||||||
const char *username = Interface().Username(), *password = Interface().Password();
|
const char *username = Interface().Username(), *password = Interface().Password();
|
||||||
|
|
||||||
if(*userLength == strlen(username) && *passwordLength == strlen(password)
|
if (*userLength == strlen(username) && *passwordLength == strlen(password)
|
||||||
&& !strncmp(peerUsername, username, *userLength)
|
&& !strncmp(peerUsername, username, *userLength)
|
||||||
&& !strncmp(peerPassword, password, *passwordLength)) {
|
&& !strncmp(peerPassword, password, *passwordLength)) {
|
||||||
NewState(ACCEPTED);
|
NewState(ACCEPTED);
|
||||||
@@ -357,60 +369,68 @@ PAP::RREvent(struct mbuf *packet)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PAP::RAEvent(struct mbuf *packet)
|
PAP::RAEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("PAP: RAEvent() state=%d\n", State());
|
TRACE("PAP: RAEvent() state=%d\n", State());
|
||||||
|
|
||||||
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &lcp_hdr = bufferheader.Data();
|
||||||
|
if (fRequestID != lcp_hdr.id) {
|
||||||
// this packet is not a reply to our request
|
// this packet is not a reply to our request
|
||||||
|
|
||||||
// TODO: log this event
|
// TODO: log this event
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(State()) {
|
switch (State()) {
|
||||||
case REQ_SENT:
|
case REQ_SENT:
|
||||||
NewState(ACCEPTED);
|
NewState(ACCEPTED);
|
||||||
Interface().StateMachine().LocalAuthenticationAccepted(
|
Interface().StateMachine().LocalAuthenticationAccepted(
|
||||||
Interface().Username());
|
Interface().Username());
|
||||||
UpEvent();
|
UpEvent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PAP::RNEvent(struct mbuf *packet)
|
PAP::RNEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("PAP: RNEvent() state=%d\n", State());
|
TRACE("PAP: RNEvent() state=%d\n", State());
|
||||||
|
|
||||||
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &lcp_hdr = bufferheader.Data();
|
||||||
|
if (fRequestID != lcp_hdr.id) {
|
||||||
// this packet is not a reply to our request
|
// this packet is not a reply to our request
|
||||||
|
|
||||||
// TODO: log this event
|
// TODO: log this event
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(State()) {
|
switch (State()) {
|
||||||
case REQ_SENT:
|
case REQ_SENT:
|
||||||
NewState(INITIAL);
|
NewState(INITIAL);
|
||||||
Interface().StateMachine().LocalAuthenticationDenied(
|
Interface().StateMachine().LocalAuthenticationDenied(
|
||||||
Interface().Username());
|
Interface().Username());
|
||||||
UpFailedEvent();
|
UpFailedEvent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -425,72 +445,76 @@ bool
|
|||||||
PAP::SendRequest()
|
PAP::SendRequest()
|
||||||
{
|
{
|
||||||
TRACE("PAP: SendRequest() state=%d\n", State());
|
TRACE("PAP: SendRequest() state=%d\n", State());
|
||||||
|
|
||||||
--fRequestCounter;
|
--fRequestCounter;
|
||||||
fNextTimeout = system_time() + kPAPTimeout;
|
fNextTimeout = system_time() + kPAPTimeout;
|
||||||
|
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
net_buffer *packet = gBufferModule->create(256);
|
||||||
if(!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
ppp_lcp_packet *request;
|
||||||
|
gBufferModule->append_size(packet, 1492, (void **)&request);
|
||||||
|
|
||||||
const char *username = Interface().Username(), *password = Interface().Password();
|
const char *username = Interface().Username(), *password = Interface().Password();
|
||||||
|
uint16 packcketLenth = 6 + strlen(username) + strlen(password);
|
||||||
packet->m_pkthdr.len = packet->m_len = 6 + strlen(username) + strlen(password);
|
// 6 : lcp header 4 byte + username length 1 byte + password length 1 byte
|
||||||
|
|
||||||
// reserve some space for overhead (we are lazy and reserve too much)
|
|
||||||
packet->m_data += Interface().PacketOverhead();
|
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
|
||||||
request->code = PPP_CONFIGURE_REQUEST;
|
request->code = PPP_CONFIGURE_REQUEST;
|
||||||
request->id = fRequestID = NextID();
|
request->id = fRequestID = NextID();
|
||||||
request->length = htons(packet->m_len);
|
request->length = htons(packcketLenth);
|
||||||
uint8 *data = request->data;
|
uint8 *data = request->data;
|
||||||
data[0] = strlen(username);
|
data[0] = strlen(username);
|
||||||
memcpy(data + 1, username, strlen(username));
|
memcpy(data + 1, username, strlen(username));
|
||||||
data[1 + data[0]] = strlen(password);
|
data[1 + data[0]] = strlen(password);
|
||||||
memcpy(data + 2 + data[0], password, strlen(password));
|
memcpy(data + 2 + data[0], password, strlen(password));
|
||||||
|
|
||||||
|
gBufferModule->trim(packet, packcketLenth);
|
||||||
|
|
||||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PAP::SendAck(struct mbuf *packet)
|
PAP::SendAck(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("PAP: SendAck() state=%d\n", State());
|
TRACE("PAP: SendAck() state=%d\n", State());
|
||||||
|
|
||||||
if(!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ppp_lcp_packet *ack = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
ack->code = PPP_CONFIGURE_ACK;
|
if (bufferheader.Status() != B_OK)
|
||||||
packet->m_len = 5;
|
return false;
|
||||||
if(packet->m_flags & M_PKTHDR)
|
ppp_lcp_packet &ack = bufferheader.Data();
|
||||||
packet->m_pkthdr.len = 5;
|
|
||||||
ack->length = htons(packet->m_len);
|
ack.code = PPP_CONFIGURE_ACK;
|
||||||
|
ack.length = htons(5);
|
||||||
ack->data[0] = 0;
|
ack.data[0] = 0;
|
||||||
|
gBufferModule->trim(packet, 5);
|
||||||
|
|
||||||
|
bufferheader.Sync();
|
||||||
|
|
||||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PAP::SendNak(struct mbuf *packet)
|
PAP::SendNak(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("PAP: SendNak() state=%d\n", State());
|
ERROR("PAP: SendNak() state=%d\n", State());
|
||||||
|
|
||||||
if(!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
nak->code = PPP_CONFIGURE_NAK;
|
if (bufferheader.Status() != B_OK)
|
||||||
packet->m_len = 5;
|
return false;
|
||||||
if(packet->m_flags & M_PKTHDR)
|
ppp_lcp_packet &nak = bufferheader.Data();
|
||||||
packet->m_pkthdr.len = 5;
|
nak.code = PPP_CONFIGURE_NAK;
|
||||||
nak->length = htons(packet->m_len);
|
nak.length = htons(5);
|
||||||
|
nak.data[0] = 0;
|
||||||
nak->data[0] = 0;
|
gBufferModule->trim(packet, 5);
|
||||||
|
|
||||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,11 +31,12 @@ class PAP;
|
|||||||
class PAPHandler : public KPPPOptionHandler {
|
class PAPHandler : public KPPPOptionHandler {
|
||||||
public:
|
public:
|
||||||
PAPHandler(PAP& owner, KPPPInterface& interface);
|
PAPHandler(PAP& owner, KPPPInterface& interface);
|
||||||
|
|
||||||
PAP& Owner() const
|
PAP& Owner() const
|
||||||
{ return fOwner; }
|
{ return fOwner; }
|
||||||
|
|
||||||
virtual status_t AddToRequest(KPPPConfigurePacket& request);
|
virtual status_t AddToRequest(KPPPConfigurePacket& request);
|
||||||
|
virtual status_t SendingAck(const KPPPConfigurePacket&);
|
||||||
virtual status_t ParseRequest(const KPPPConfigurePacket& request,
|
virtual status_t ParseRequest(const KPPPConfigurePacket& request,
|
||||||
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject);
|
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject);
|
||||||
|
|
||||||
@@ -48,17 +49,17 @@ class PAP : public KPPPProtocol {
|
|||||||
public:
|
public:
|
||||||
PAP(KPPPInterface& interface, driver_parameter *settings);
|
PAP(KPPPInterface& interface, driver_parameter *settings);
|
||||||
virtual ~PAP();
|
virtual ~PAP();
|
||||||
|
|
||||||
virtual status_t InitCheck() const;
|
virtual status_t InitCheck() const;
|
||||||
|
|
||||||
pap_state State() const
|
pap_state State() const
|
||||||
{ return fState; }
|
{ return fState; }
|
||||||
|
|
||||||
virtual bool Up();
|
virtual bool Up();
|
||||||
virtual bool Down();
|
virtual bool Down();
|
||||||
|
|
||||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber);
|
virtual status_t Send(net_buffer *packet, uint16 protocolNumber);
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -66,28 +67,28 @@ class PAP : public KPPPProtocol {
|
|||||||
void NewState(pap_state next);
|
void NewState(pap_state next);
|
||||||
uint8 NextID();
|
uint8 NextID();
|
||||||
// return the next id for PAP packets
|
// return the next id for PAP packets
|
||||||
|
|
||||||
// events
|
// events
|
||||||
void TOGoodEvent();
|
void TOGoodEvent();
|
||||||
void TOBadEvent();
|
void TOBadEvent();
|
||||||
void RREvent(struct mbuf *packet);
|
void RREvent(net_buffer *packet);
|
||||||
void RAEvent(struct mbuf *packet);
|
void RAEvent(net_buffer *packet);
|
||||||
void RNEvent(struct mbuf *packet);
|
void RNEvent(net_buffer *packet);
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
void ReportUpFailedEvent();
|
void ReportUpFailedEvent();
|
||||||
void ReportUpEvent();
|
void ReportUpEvent();
|
||||||
void ReportDownEvent();
|
void ReportDownEvent();
|
||||||
void InitializeRestartCount();
|
void InitializeRestartCount();
|
||||||
bool SendRequest();
|
bool SendRequest();
|
||||||
bool SendAck(struct mbuf *packet);
|
bool SendAck(net_buffer *packet);
|
||||||
bool SendNak(struct mbuf *packet);
|
bool SendNak(net_buffer *packet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// for state machine
|
// for state machine
|
||||||
pap_state fState;
|
pap_state fState;
|
||||||
vint32 fID;
|
int32 fID;
|
||||||
|
|
||||||
// counters and timers
|
// counters and timers
|
||||||
int32 fMaxRequest;
|
int32 fMaxRequest;
|
||||||
int32 fRequestCounter;
|
int32 fRequestCounter;
|
||||||
|
|||||||
@@ -5,42 +5,41 @@
|
|||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
#include <net_module.h>
|
#include <net_buffer.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
#include <KPPPModule.h>
|
#include <KPPPModule.h>
|
||||||
|
|
||||||
#include "Protocol.h"
|
#include "Protocol.h"
|
||||||
|
|
||||||
|
#define PAP_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/pap"
|
||||||
|
|
||||||
#define PAP_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pap"
|
net_stack_module_info *gStackModule = NULL;
|
||||||
|
net_buffer_module_info *gBufferModule = NULL;
|
||||||
struct core_module_info *core = NULL;
|
|
||||||
status_t std_ops(int32 op, ...);
|
status_t std_ops(int32 op, ...);
|
||||||
|
|
||||||
|
static bool
|
||||||
static
|
|
||||||
bool
|
|
||||||
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
||||||
driver_parameter *settings, ppp_module_key_type type)
|
driver_parameter *settings, ppp_module_key_type type)
|
||||||
{
|
{
|
||||||
if(type != PPP_AUTHENTICATOR_KEY_TYPE)
|
if (type != PPP_AUTHENTICATOR_KEY_TYPE)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
PAP *pap;
|
PAP *pap;
|
||||||
bool success;
|
bool success;
|
||||||
if(subInterface) {
|
if (subInterface) {
|
||||||
pap = new PAP(*subInterface, settings);
|
pap = new PAP(*subInterface, settings);
|
||||||
success = subInterface->AddProtocol(pap);
|
success = subInterface->AddProtocol(pap);
|
||||||
} else {
|
} else {
|
||||||
pap = new PAP(mainInterface, settings);
|
pap = new PAP(mainInterface, settings);
|
||||||
success = mainInterface.AddProtocol(pap);
|
success = mainInterface.AddProtocol(pap);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("PAP: add_to(): %s\n",
|
TRACE("PAP: add_to(): %s\n",
|
||||||
success && pap && pap->InitCheck() == B_OK ? "OK" : "ERROR");
|
success && pap && pap->InitCheck() == B_OK ? "OK" : "ERROR");
|
||||||
|
|
||||||
return success && pap && pap->InitCheck() == B_OK;
|
return success && pap && pap->InitCheck() == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,22 +57,28 @@ static ppp_module_info pap_module = {
|
|||||||
|
|
||||||
_EXPORT
|
_EXPORT
|
||||||
status_t
|
status_t
|
||||||
std_ops(int32 op, ...)
|
std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch (op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT:
|
||||||
if(get_module(NET_CORE_MODULE_NAME, (module_info**) &core) != B_OK)
|
if (get_module(NET_STACK_MODULE_NAME, (module_info**) &gStackModule) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
if (get_module(NET_BUFFER_MODULE_NAME,
|
||||||
|
(module_info **)&gBufferModule) != B_OK) {
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
put_module(NET_CORE_MODULE_NAME);
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel network ppp ppp ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
|
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||||
|
# Needed for <support/Errors.h> and maybe other stuff.
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
|
# We need the public network headers also when not compiling for Haiku.
|
||||||
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
|
UsePrivateHeaders net ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
KernelAddon ppp :
|
||||||
|
ppp.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
HaikuInstall install-networking :
|
||||||
|
/boot/home/config/add-ons/kernel/network/ppp
|
||||||
|
: ppp ;
|
||||||
@@ -0,0 +1,388 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Lin Longzhou, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net/if_media.h>
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <ethernet.h>
|
||||||
|
#include <ether_driver.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_datalink_protocol.h>
|
||||||
|
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <KPPPManager.h>
|
||||||
|
#include <ppp_device.h>
|
||||||
|
|
||||||
|
#define PPP_HEADER_LENGTH (8 + ETHER_HEADER_LENGTH)
|
||||||
|
|
||||||
|
|
||||||
|
net_buffer* create_buffer_for_frame(uint8 *frame, uint16 frame_size);
|
||||||
|
|
||||||
|
static const bigtime_t kLinkCheckInterval = 1000000;
|
||||||
|
// 1 second
|
||||||
|
|
||||||
|
net_buffer_module_info *gBufferModule;
|
||||||
|
ppp_interface_module_info* gPPPInterfaceModule;
|
||||||
|
static net_stack_module_info *sStackModule;
|
||||||
|
|
||||||
|
static mutex sListLock;
|
||||||
|
static DoublyLinkedList<ppp_device> sCheckList;
|
||||||
|
static sem_id sLinkChangeSemaphore;
|
||||||
|
static thread_id sLinkCheckerThread;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
//
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_init(const char *name, net_device **_device)
|
||||||
|
{
|
||||||
|
// ppp device
|
||||||
|
dprintf("%s: entering!\n", __func__);
|
||||||
|
|
||||||
|
if (strncmp(name, "ppp", 3)) {
|
||||||
|
dprintf("[%s] not ppp device\n", name);
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("[%s] is ppp device\n", name);
|
||||||
|
|
||||||
|
status_t status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// ppp_device *device = new (std::nothrow) ppp_device;
|
||||||
|
ppp_interface_id idInterface = gPPPInterfaceModule->CreateInterfaceWithName(name, 0);
|
||||||
|
KPPPInterface * pppInterface = gPPPInterfaceModule->GetInterface(idInterface);
|
||||||
|
|
||||||
|
if (idInterface <= 0 || pppInterface == NULL) {
|
||||||
|
if (idInterface <= 0)
|
||||||
|
dprintf("%s: idInterface:%ld\n", __func__, idInterface);
|
||||||
|
else
|
||||||
|
dprintf("%s: pppInterface == NULL %ld\n", __func__, idInterface);
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ifnet available until interface up phase
|
||||||
|
ppp_device *device = (ppp_device *)pppInterface->Ifnet();
|
||||||
|
if (device == NULL) {
|
||||||
|
dprintf("%s: can not get ppp_device\n", __func__);
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(device->name, name);
|
||||||
|
device->flags = (IFF_BROADCAST | IFF_LINK) & (~IFF_UP);
|
||||||
|
device->type = IFT_PPP;
|
||||||
|
device->mtu = 1492;
|
||||||
|
device->frame_size = 1500;
|
||||||
|
device->media = IFM_ACTIVE | IFM_ETHER;
|
||||||
|
device->header_length = PPP_HEADER_LENGTH;
|
||||||
|
|
||||||
|
status =sStackModule->init_fifo(&(device->ppp_fifo), "ppp_fifo", 10 * 1500);
|
||||||
|
// 10 ppp packet at most
|
||||||
|
if (status < B_OK)
|
||||||
|
return(status);
|
||||||
|
|
||||||
|
TRACE("[%s] finish\n", "allocate ppp_device");
|
||||||
|
*_device = device;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_uninit(net_device *device)
|
||||||
|
{
|
||||||
|
dprintf("%s: uninit ppp\n", __func__);
|
||||||
|
ppp_device *ppp_dev=(ppp_device *)device;
|
||||||
|
|
||||||
|
sStackModule->uninit_fifo(&(ppp_dev->ppp_fifo));
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
|
||||||
|
// delete ppp_dev->KPPP_Interface;
|
||||||
|
delete ppp_dev;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_up(net_device *_device)
|
||||||
|
{
|
||||||
|
dprintf("ppp_up\n");
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (device->KPPP_Interface == NULL) {
|
||||||
|
dprintf("%s: warning! can not find pppinterface KPPP_Interface\n", __func__);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->KPPP_Interface->Up() != true) {
|
||||||
|
dprintf("%s: warning! KPPP_Interface->Up() failure\n", __func__);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
device->mtu = device->frame_size - device->header_length;
|
||||||
|
// s_pppoe_dev = device;
|
||||||
|
|
||||||
|
dprintf("%s: congratulations! Find pppinterface (device->KPPP_Interface)\n", __func__);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ppp_down(net_device *_device)
|
||||||
|
{
|
||||||
|
dprintf("%s\n", __func__);
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
device->KPPP_Interface->Down();
|
||||||
|
|
||||||
|
MutexLocker _(sListLock);
|
||||||
|
|
||||||
|
// if the device is still part of the list, remove it
|
||||||
|
if (device->GetDoublyLinkedListLink()->next != NULL
|
||||||
|
|| device->GetDoublyLinkedListLink()->previous != NULL
|
||||||
|
|| device == sCheckList.Head())
|
||||||
|
sCheckList.Remove(device);
|
||||||
|
|
||||||
|
// device->KPPP_Interface = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_control(net_device *_device, int32 op, void *argument,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
TRACE("%s %ld\n", __func__, op);
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (device->KPPP_Interface == NULL) {
|
||||||
|
dprintf("%s: can not find KPPP_Interface for ppp\n", __func__);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return device->KPPP_Interface->Control(op, argument, length);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_send_data(net_device *_device, net_buffer *buffer)
|
||||||
|
{
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (buffer->size > device->frame_size || buffer->size < device->header_length) {
|
||||||
|
device->stats.send.errors++;
|
||||||
|
dprintf("sorry! fail send ppp packet, size wrong!\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->KPPP_Interface == NULL) {
|
||||||
|
device->stats.send.errors++;
|
||||||
|
dprintf("Fail send ppp packet, no eth for ppp!\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t net_buffer_size = buffer->size;
|
||||||
|
// store buffer->size in case buffer freed in KPPP_Interface->Send
|
||||||
|
status_t status = device->KPPP_Interface->Send(buffer, 0x0021); // IP_PROTOCOL 0x0021
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
device->stats.send.errors++;
|
||||||
|
dprintf("KPPP_Interface->Send(buffer, 0x0021 IP) fail\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
device->stats.send.packets++;
|
||||||
|
device->stats.send.bytes += net_buffer_size;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_receive_data(net_device *_device, net_buffer **_buffer)
|
||||||
|
{
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (device->KPPP_Interface == NULL)
|
||||||
|
return B_FILE_ERROR;
|
||||||
|
|
||||||
|
TRACE("%s: trying fifo_dequeue_buffer\n", __func__);
|
||||||
|
status_t status = sStackModule->fifo_dequeue_buffer(&(device->ppp_fifo), 0, 10000000, _buffer);
|
||||||
|
|
||||||
|
if (status < B_OK) {
|
||||||
|
TRACE("sorry! can not fifo_dequeue_buffer!\n");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (*_buffer)->interface_address = NULL; // strange need to put here
|
||||||
|
device->stats.receive.bytes += (*_buffer)->size;
|
||||||
|
device->stats.receive.packets++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_set_mtu(net_device *_device, size_t mtu)
|
||||||
|
{
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (mtu > device->frame_size - ETHER_HEADER_LENGTH - 8
|
||||||
|
|| mtu <= ETHER_HEADER_LENGTH + 8 + 10)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
device->mtu = mtu;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_set_promiscuous(net_device *_device, bool promiscuous)
|
||||||
|
{
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_set_media(net_device *device, uint32 media)
|
||||||
|
{
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_add_multicast(struct net_device *_device, const sockaddr *_address)
|
||||||
|
{
|
||||||
|
// ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (_address->sa_family != AF_LINK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
const sockaddr_dl *address = (const sockaddr_dl *)_address;
|
||||||
|
if (address->sdl_type != IFT_ETHER)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_remove_multicast(struct net_device *_device, const sockaddr *_address)
|
||||||
|
{
|
||||||
|
// ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (_address->sa_family != AF_LINK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
const sockaddr_dl *address = (const sockaddr_dl *)_address;
|
||||||
|
if (address->sdl_type != IFT_ETHER)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ppp_std_ops(int32 op, ...)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case B_MODULE_INIT:
|
||||||
|
{
|
||||||
|
status_t status = get_module(NET_STACK_MODULE_NAME,
|
||||||
|
(module_info **)&sStackModule);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = get_module(PPP_INTERFACE_MODULE_NAME,
|
||||||
|
(module_info**)&gPPPInterfaceModule);
|
||||||
|
if (status < B_OK) {
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
new (&sCheckList) DoublyLinkedList<ppp_device>;
|
||||||
|
// static C++ objects are not initialized in the module startup
|
||||||
|
|
||||||
|
sLinkCheckerThread = -1;
|
||||||
|
|
||||||
|
sLinkChangeSemaphore = create_sem(0, "ppp link change");
|
||||||
|
if (sLinkChangeSemaphore < B_OK) {
|
||||||
|
put_module(PPP_INTERFACE_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return sLinkChangeSemaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_init(&sListLock, "ppp devices");
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_MODULE_UNINIT:
|
||||||
|
{
|
||||||
|
delete_sem(sLinkChangeSemaphore);
|
||||||
|
|
||||||
|
status_t status;
|
||||||
|
wait_for_thread(sLinkCheckerThread, &status);
|
||||||
|
|
||||||
|
mutex_destroy(&sListLock);
|
||||||
|
|
||||||
|
put_module(PPP_INTERFACE_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
net_device_module_info spppModule = {
|
||||||
|
{
|
||||||
|
"network/devices/ppp/v1",
|
||||||
|
0,
|
||||||
|
ppp_std_ops
|
||||||
|
},
|
||||||
|
ppp_init,
|
||||||
|
ppp_uninit,
|
||||||
|
ppp_up,
|
||||||
|
ppp_down,
|
||||||
|
ppp_control,
|
||||||
|
ppp_send_data,
|
||||||
|
ppp_receive_data,
|
||||||
|
ppp_set_mtu,
|
||||||
|
ppp_set_promiscuous,
|
||||||
|
ppp_set_media,
|
||||||
|
ppp_add_multicast,
|
||||||
|
ppp_remove_multicast,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module_info *modules[] = {
|
||||||
|
(module_info *)&spppModule,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
|
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
|
# We need the public network headers also when not compiling for Haiku.
|
||||||
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
|
UsePrivateHeaders kernel net ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
KernelAddon ppp_frame :
|
||||||
|
ppp_frame.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||||
|
: ppp_frame ;
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Lin Longzhou, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ethernet.h>
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <net_datalink_protocol.h>
|
||||||
|
#include <net_datalink.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <PPPControl.h>
|
||||||
|
#include <ppp_device.h>
|
||||||
|
|
||||||
|
struct ppp_frame_protocol : net_datalink_protocol {
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static net_stack_module_info *sStackModule;
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_deframe(net_device* device, net_buffer* buffer)
|
||||||
|
{
|
||||||
|
TRACE("%s: buffer type:%lx\n", __func__, buffer->type);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_init(struct net_interface* interface, net_domain* domain,
|
||||||
|
net_datalink_protocol** _protocol)
|
||||||
|
{
|
||||||
|
// We only support a single type!
|
||||||
|
dprintf("in function: %s::%s\n", __FILE__, __func__);
|
||||||
|
if (interface->device->type != IFT_PPP)
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
|
ppp_frame_protocol* protocol;
|
||||||
|
|
||||||
|
status_t status = sStackModule->register_device_deframer(interface->device,
|
||||||
|
&ppp_deframe);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = sStackModule->register_domain_device_handler(
|
||||||
|
interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE), domain);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = sStackModule->register_domain_device_handler(
|
||||||
|
interface->device, B_NET_FRAME_TYPE_IPV4, domain);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// Locally received buffers don't need a domain device handler, as the
|
||||||
|
// buffer reception is handled internally.
|
||||||
|
|
||||||
|
protocol = new(std::nothrow) ppp_frame_protocol;
|
||||||
|
if (protocol == NULL) {
|
||||||
|
sStackModule->unregister_device_deframer(interface->device);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_protocol = protocol;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_uninit(net_datalink_protocol* protocol)
|
||||||
|
{
|
||||||
|
sStackModule->unregister_device_deframer(protocol->interface->device);
|
||||||
|
sStackModule->unregister_device_handler(protocol->interface->device, 0);
|
||||||
|
|
||||||
|
delete protocol;
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_send_data(net_datalink_protocol* protocol, net_buffer* buffer)
|
||||||
|
{
|
||||||
|
TRACE("%s: next module is %s\n", __func__, protocol->next->module->info.name);
|
||||||
|
return protocol->next->module->send_data(protocol->next, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_up(net_datalink_protocol* protocol)
|
||||||
|
{
|
||||||
|
dprintf("in function: %s\n", __func__);
|
||||||
|
|
||||||
|
return protocol->next->module->interface_up(protocol->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ppp_frame_down(net_datalink_protocol* protocol)
|
||||||
|
{
|
||||||
|
dprintf("%s::%s: entry\n", __FILE__, __func__);
|
||||||
|
protocol->next->module->interface_down(protocol->next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_change_address(net_datalink_protocol* protocol,
|
||||||
|
net_interface_address* address, int32 option,
|
||||||
|
const struct sockaddr* oldAddress, const struct sockaddr* newAddress)
|
||||||
|
{
|
||||||
|
TRACE("in function: %s::%s\n", __FILE__, __func__);
|
||||||
|
return protocol->next->module->change_address(protocol->next, address,
|
||||||
|
option, oldAddress, newAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
PPP_module_control(int32 option, void* argument, size_t length)
|
||||||
|
{
|
||||||
|
// control_net_module_args* args=(control_net_module_args*)argument;
|
||||||
|
|
||||||
|
if (option < PPPC_CONTROL_MODULE || option > PPP_CONTROL_OPS_END)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// if (args->name != PPP_INTERFACE_MODULE_NAME)
|
||||||
|
// return B_ERROR;
|
||||||
|
|
||||||
|
switch(option)
|
||||||
|
{
|
||||||
|
case PPPC_CREATE_INTERFACE:
|
||||||
|
// process_CreateInterface(args->data, args->length);
|
||||||
|
case PPPC_CREATE_INTERFACE_WITH_NAME:
|
||||||
|
case PPPC_DELETE_INTERFACE:
|
||||||
|
case PPPC_BRING_INTERFACE_UP:
|
||||||
|
case PPPC_BRING_INTERFACE_DOWN:
|
||||||
|
case PPPC_CONTROL_INTERFACE:
|
||||||
|
case PPPC_GET_INTERFACES:
|
||||||
|
case PPPC_COUNT_INTERFACES:
|
||||||
|
case PPPC_FIND_INTERFACE_WITH_SETTINGS:
|
||||||
|
|
||||||
|
// interface control
|
||||||
|
case PPPC_GET_INTERFACE_INFO:
|
||||||
|
case PPPC_SET_USERNAME:
|
||||||
|
case PPPC_SET_PASSWORD:
|
||||||
|
case PPPC_SET_ASK_BEFORE_CONNECTING:
|
||||||
|
// ppp_up uses this in order to finalize a connection request
|
||||||
|
case PPPC_SET_MRU:
|
||||||
|
case PPPC_SET_CONNECT_ON_DEMAND:
|
||||||
|
case PPPC_SET_AUTO_RECONNECT:
|
||||||
|
case PPPC_HAS_INTERFACE_SETTINGS:
|
||||||
|
case PPPC_GET_STATISTICS:
|
||||||
|
// handler access
|
||||||
|
case PPPC_CONTROL_DEVICE:
|
||||||
|
case PPPC_CONTROL_PROTOCOL:
|
||||||
|
case PPPC_CONTROL_OPTION_HANDLER:
|
||||||
|
case PPPC_CONTROL_LCP_EXTENSION:
|
||||||
|
case PPPC_CONTROL_CHILD:
|
||||||
|
// KPPPDevice
|
||||||
|
case PPPC_GET_DEVICE_INFO:
|
||||||
|
// KPPPProtocol
|
||||||
|
case PPPC_GET_PROTOCOL_INFO:
|
||||||
|
// Common/mixed ops
|
||||||
|
case PPPC_ENABLE:
|
||||||
|
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||||
|
|
||||||
|
// these two control ops use the ppp_report_request structure
|
||||||
|
case PPPC_ENABLE_REPORTS:
|
||||||
|
case PPPC_DISABLE_REPORTS:
|
||||||
|
|
||||||
|
case PPP_CONTROL_OPS_END:
|
||||||
|
case PPPC_CONTROL_MODULE:
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ppp_frame_control(net_datalink_protocol* protocol, int32 option,
|
||||||
|
void* argument, size_t length)
|
||||||
|
{
|
||||||
|
TRACE("%s: option:%ld\n", __func__, option);
|
||||||
|
|
||||||
|
if (option >= PPPC_CONTROL_MODULE && option <=PPP_CONTROL_OPS_END)
|
||||||
|
{
|
||||||
|
status_t status =PPP_module_control(option, argument, length);
|
||||||
|
// gPPPInterfaceModule->ControlInterface(1, option, argument, length);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return protocol->next->module->control(protocol->next, option, argument,
|
||||||
|
length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ppp_frame_join_multicast(net_datalink_protocol* protocol,
|
||||||
|
const sockaddr* address)
|
||||||
|
{
|
||||||
|
TRACE("in function: %s\n", __func__);
|
||||||
|
return protocol->next->module->join_multicast(protocol->next, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ppp_frame_leave_multicast(net_datalink_protocol* protocol,
|
||||||
|
const sockaddr* address)
|
||||||
|
{
|
||||||
|
TRACE("in function: %s\n", __func__);
|
||||||
|
return protocol->next->module->leave_multicast(protocol->next, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
pppoe_frame_std_ops(int32 op, ...)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case B_MODULE_INIT:
|
||||||
|
if (get_module(NET_STACK_MODULE_NAME,
|
||||||
|
(module_info **)&sStackModule) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
case B_MODULE_UNINIT:
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static net_datalink_protocol_module_info sPPPFrameModule = {
|
||||||
|
{
|
||||||
|
"network/datalink_protocols/ppp_frame/v1",
|
||||||
|
0,
|
||||||
|
pppoe_frame_std_ops
|
||||||
|
},
|
||||||
|
ppp_frame_init,
|
||||||
|
ppp_frame_uninit,
|
||||||
|
ppp_frame_send_data,
|
||||||
|
ppp_frame_up,
|
||||||
|
ppp_frame_down,
|
||||||
|
ppp_frame_change_address,
|
||||||
|
ppp_frame_control,
|
||||||
|
ppp_frame_join_multicast,
|
||||||
|
ppp_frame_leave_multicast,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module_info* modules[] = {
|
||||||
|
(module_info*)&sPPPFrameModule,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
|
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
|
# We need the public network headers also when not compiling for Haiku.
|
||||||
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
|
# UsePrivateHeaders net ;
|
||||||
|
|
||||||
|
UsePrivateHeaders kernel net ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
KernelAddon KPPPManager :
|
||||||
|
KPPPManager.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
LinkAgainst KPPPManager : libkernelppp.a ;
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||||
|
: KPPPManager ;
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2014, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
* Lin Longzhou, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <net_stack.h>
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <ppp_device.h>
|
||||||
|
#include <KPPPManager.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct entry_private : ppp_interface_entry, DoublyLinkedListLinkImpl<entry_private> {
|
||||||
|
};
|
||||||
|
|
||||||
|
static DoublyLinkedList<entry_private> sEntryList;
|
||||||
|
|
||||||
|
net_buffer_module_info* gBufferModule = NULL;
|
||||||
|
net_stack_module_info* gStackModule = NULL;
|
||||||
|
// static struct net_interface* sinterface;
|
||||||
|
static mutex sListLock;
|
||||||
|
static uint32 ppp_interface_count;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
static KPPPInterface * GetInterface(ppp_interface_id ID);
|
||||||
|
|
||||||
|
static ppp_interface_id
|
||||||
|
CreateInterface(const driver_settings *settings, ppp_interface_id parentID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
if (parentID > 0) {
|
||||||
|
TRACE("Not support Multi_Link yet!\n");
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings == NULL) {
|
||||||
|
TRACE("No driver_settings yet!\n");
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_interface_count++;
|
||||||
|
|
||||||
|
if (GetInterface(ppp_interface_count) != NULL)
|
||||||
|
return 0l;
|
||||||
|
|
||||||
|
entry_private* pentry = new (std::nothrow) entry_private;
|
||||||
|
memset(pentry, 0, sizeof(entry_private));
|
||||||
|
pentry->accessing = ppp_interface_count;
|
||||||
|
sEntryList.Add(pentry);
|
||||||
|
|
||||||
|
KPPPInterface *device = new (std::nothrow) KPPPInterface(NULL,
|
||||||
|
pentry, ppp_interface_count, NULL, NULL);
|
||||||
|
|
||||||
|
if (device == NULL || pentry == NULL) {
|
||||||
|
TRACE("device or pentry is NULL\n");
|
||||||
|
ppp_interface_count--;
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
|
||||||
|
|
||||||
|
return ppp_interface_count; // only support 1 ppp connection right now
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ppp_interface_id
|
||||||
|
CreateInterfaceWithName(const char *name, ppp_interface_id parentID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
if (parentID > 0) {
|
||||||
|
dprintf("Not support Multi_Link yet!\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(name, "ppp", 3)) {
|
||||||
|
dprintf("%s is not ppp device!\n", name);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_interface_count++;
|
||||||
|
if (GetInterface(ppp_interface_count) != NULL) {
|
||||||
|
TRACE("PPP Interface already exist!\n");
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_private* pentry = new (std::nothrow) entry_private;
|
||||||
|
memset(pentry, 0, sizeof(entry_private));
|
||||||
|
pentry->accessing = ppp_interface_count;
|
||||||
|
sEntryList.Add(pentry);
|
||||||
|
|
||||||
|
KPPPInterface* device = new (std::nothrow) KPPPInterface(name,
|
||||||
|
pentry, ppp_interface_count, NULL, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
if (device == NULL || pentry == NULL) {
|
||||||
|
TRACE("can not create ppp interface!\n");
|
||||||
|
ppp_interface_count--;
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
|
||||||
|
|
||||||
|
return ppp_interface_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
DeleteInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||||
|
pentry->deleting = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
RemoveInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
if (ID <= 0 || ID > ppp_interface_count)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||||
|
pentry->deleting = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static net_device *
|
||||||
|
RegisterInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
// MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
entry_private* entry = NULL;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||||
|
entry = pentry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ppp_device *device = new (std::nothrow) ppp_device;
|
||||||
|
if (device == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset(device, 0, sizeof(ppp_device));
|
||||||
|
device->KPPP_Interface = entry->interface;
|
||||||
|
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static KPPPInterface *
|
||||||
|
GetInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
// MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
TRACE("testing interface id:%ld\n", pentry->accessing);
|
||||||
|
if ((ppp_interface_id)(pentry->accessing) == ID) {
|
||||||
|
TRACE("get interface id:%ld\n", ID);
|
||||||
|
return pentry->interface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("can not get interface id:%ld\n", ID);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
UnregisterInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
if (ID <= 0 || ID > ppp_interface_count)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t length)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
if (ID <= 0 || ID > ppp_interface_count)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
if ((ppp_interface_id)pentry->accessing == ID)
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32
|
||||||
|
GetInterfaces(ppp_interface_id *interfaces, int32 count, ppp_interface_filter filter)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock);
|
||||||
|
|
||||||
|
if (count <= 0 || count > (int32)ppp_interface_count)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
uint32 ppp_count = 0;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
interfaces[ppp_count] = pentry->accessing;
|
||||||
|
ppp_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ppp_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32
|
||||||
|
CountInterfaces(ppp_interface_filter filter)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
uint32 ppp_count = 0;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
iterator.Next();
|
||||||
|
ppp_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ppp_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
EnableReports(ppp_report_type type, thread_id thread, int32 flags)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
return; // need more portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DisableReports(ppp_report_type type, thread_id thread)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
return; // need more portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
DoesReport(ppp_report_type type, thread_id thread)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
return false; // need more portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
KPPPManager_std_ops(int32 op, ...)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case B_MODULE_INIT:
|
||||||
|
mutex_init(&sListLock, "KPPPManager");
|
||||||
|
new (&sEntryList) DoublyLinkedList<entry_private>;
|
||||||
|
// static C++ objects are not initialized in the module startup
|
||||||
|
ppp_interface_count = 0;
|
||||||
|
|
||||||
|
if (get_module(NET_STACK_MODULE_NAME, (module_info**)&gStackModule)
|
||||||
|
!= B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule)
|
||||||
|
!= B_OK) {
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
case B_MODULE_UNINIT:
|
||||||
|
mutex_destroy(&sListLock);
|
||||||
|
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ppp_interface_module_info sKPPPManagerModule = {
|
||||||
|
{
|
||||||
|
PPP_INTERFACE_MODULE_NAME,
|
||||||
|
0,
|
||||||
|
KPPPManager_std_ops
|
||||||
|
},
|
||||||
|
CreateInterface,
|
||||||
|
CreateInterfaceWithName,
|
||||||
|
DeleteInterface,
|
||||||
|
RemoveInterface,
|
||||||
|
RegisterInterface,
|
||||||
|
GetInterface,
|
||||||
|
UnregisterInterface,
|
||||||
|
ControlInterface,
|
||||||
|
GetInterfaces,
|
||||||
|
CountInterfaces,
|
||||||
|
EnableReports,
|
||||||
|
DisableReports,
|
||||||
|
DoesReport
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module_info* modules[] = {
|
||||||
|
(module_info*)&sKPPPManagerModule,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -3,11 +3,12 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
|
|
||||||
#include "DiscoveryPacket.h"
|
#include "DiscoveryPacket.h"
|
||||||
|
|
||||||
#include <core_funcs.h>
|
|
||||||
|
|
||||||
|
|
||||||
DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID)
|
DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID)
|
||||||
: fCode(code),
|
: fCode(code),
|
||||||
fSessionID(sessionID),
|
fSessionID(sessionID),
|
||||||
@@ -16,18 +17,26 @@ DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start)
|
DiscoveryPacket::DiscoveryPacket(net_buffer *packet, uint32 start)
|
||||||
{
|
{
|
||||||
// decode packet
|
// decode packet
|
||||||
uint8 *data = mtod(packet, uint8*);
|
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||||
data += start;
|
if (bufferheader.Status() != B_OK) {
|
||||||
pppoe_header *header = (pppoe_header*) data;
|
dprintf("NetBufferHeaderReader create fail\n");
|
||||||
|
fInitStatus = B_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pppoe_header &header = bufferheader.Data();
|
||||||
|
|
||||||
SetCode(header->code);
|
SetCode(header.code);
|
||||||
|
|
||||||
uint16 length = ntohs(header->length);
|
uint16 length = ntohs(header.length);
|
||||||
|
|
||||||
if(length > packet->m_len - PPPoE_HEADER_SIZE - start) {
|
if(length > packet->size - PPPoE_HEADER_SIZE) {
|
||||||
|
dprintf("packet size less than pppoe payload\n");
|
||||||
|
dprintf("pppoe payload:%d\n", length);
|
||||||
|
dprintf("PPPoE_HEADER_SIZE:%d\n", PPPoE_HEADER_SIZE);
|
||||||
|
dprintf("packet->size:%ld\n", packet->size);
|
||||||
fInitStatus = B_ERROR;
|
fInitStatus = B_ERROR;
|
||||||
return;
|
return;
|
||||||
// there are no tags (or one corrupted tag)
|
// there are no tags (or one corrupted tag)
|
||||||
@@ -37,7 +46,7 @@ DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start)
|
|||||||
pppoe_tag *tag;
|
pppoe_tag *tag;
|
||||||
|
|
||||||
while(position <= 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), tag->data, ntohs(tag->length));
|
AddTag(ntohs(tag->type), tag->data, ntohs(tag->length));
|
||||||
@@ -116,13 +125,21 @@ DiscoveryPacket::TagWithType(uint16 type) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct mbuf*
|
net_buffer*
|
||||||
DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
DiscoveryPacket::ToNetBuffer(uint32 MTU)
|
||||||
{
|
{
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
net_buffer *packet = gBufferModule->create(256);
|
||||||
packet->m_data += reserve;
|
if (packet == NULL) {
|
||||||
|
dprintf("create buffer failure\n");
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pppoe_header *header ;
|
||||||
|
status_t status = gBufferModule->append_size(packet, 1492, (void **)&header);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf("append size failure\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
header->version = PPPoE_VERSION;
|
header->version = PPPoE_VERSION;
|
||||||
header->type = PPPoE_TYPE;
|
header->type = PPPoE_TYPE;
|
||||||
@@ -137,7 +154,7 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
|||||||
|
|
||||||
// make sure we have enough space left
|
// make sure we have enough space left
|
||||||
if(MTU - length < tag->length) {
|
if(MTU - length < tag->length) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +167,11 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
|||||||
}
|
}
|
||||||
|
|
||||||
header->length = htons(length);
|
header->length = htons(length);
|
||||||
packet->m_pkthdr.len = packet->m_len = length + PPPoE_HEADER_SIZE;
|
status = gBufferModule->trim(packet, length + PPPoE_HEADER_SIZE);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf("trim buffer failure\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <TemplateList.h>
|
#include <TemplateList.h>
|
||||||
|
|
||||||
|
#define ETHER_HDR_LEN 14
|
||||||
|
|
||||||
enum PPPoE_TAG_TYPE {
|
enum PPPoE_TAG_TYPE {
|
||||||
END_OF_LIST = 0x0000,
|
END_OF_LIST = 0x0000,
|
||||||
@@ -37,13 +38,13 @@ typedef struct pppoe_tag {
|
|||||||
uint16 type;
|
uint16 type;
|
||||||
uint16 length;
|
uint16 length;
|
||||||
uint8 data[0];
|
uint8 data[0];
|
||||||
};
|
} pppoe_tag;
|
||||||
|
|
||||||
|
|
||||||
class DiscoveryPacket {
|
class DiscoveryPacket {
|
||||||
public:
|
public:
|
||||||
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
|
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
|
||||||
DiscoveryPacket(struct mbuf *packet, uint32 start = 0);
|
DiscoveryPacket(net_buffer *packet, uint32 start = 0);
|
||||||
~DiscoveryPacket();
|
~DiscoveryPacket();
|
||||||
|
|
||||||
status_t InitCheck() const
|
status_t InitCheck() const
|
||||||
@@ -66,8 +67,8 @@ 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 MTU, uint32 reserve = ETHER_HDR_LEN);
|
net_buffer *ToNetBuffer(uint32 MTU);
|
||||||
// the user is responsible for freeing the mbuf
|
// the user is responsible for freeing the net_buffer
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 fCode;
|
uint8 fCode;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
SubDir HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
if $(TARGET_PLATFORM) != haiku {
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
# for kernel_cpp.h and BLocker
|
UsePrivateKernelHeaders ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
UsePrivateHeaders [ FDirName kernel ] ;
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
libkernelppp headers ] : true ;
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
SubDirC++Flags -fno-rtti ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
KernelAddon pppoe :
|
KernelAddon pppoe :
|
||||||
pppoe.cpp
|
pppoe.cpp
|
||||||
PPPoEDevice.cpp
|
PPPoEDevice.cpp
|
||||||
@@ -32,5 +26,5 @@ LinkAgainst pppoe : libkernelppp.a ;
|
|||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
HaikuInstall install-networking
|
HaikuInstall install-networking
|
||||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
: /boot/home/config/add-ons/kernel/haiku/ppp
|
||||||
: pppoe ;
|
: pppoe ;
|
||||||
|
|||||||
@@ -8,10 +8,15 @@
|
|||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/if_ether.h>
|
|
||||||
|
#include <ethernet.h>
|
||||||
|
#include <ether_driver.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
class PPPoEDevice;
|
class PPPoEDevice;
|
||||||
|
|
||||||
|
#define B_NET_FRAME_TYPE_PPPOE B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE)
|
||||||
|
#define B_NET_FRAME_TYPE_PPPOE_DISCOVERY B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE_DISCOVERY)
|
||||||
|
|
||||||
#define PPPoE_QUERY_REPORT_SIZE 2048
|
#define PPPoE_QUERY_REPORT_SIZE 2048
|
||||||
#define PPPoE_QUERY_REPORT 'PoEQ'
|
#define PPPoE_QUERY_REPORT 'PoEQ'
|
||||||
@@ -60,14 +65,14 @@ typedef struct complete_pppoe_header {
|
|||||||
|
|
||||||
|
|
||||||
// defined in pppoe.cpp
|
// defined in pppoe.cpp
|
||||||
extern ifnet *FindPPPoEInterface(const char *name);
|
extern net_device *FindPPPoEInterface(const char *name);
|
||||||
extern uint32 NewHostUniq();
|
extern uint32 NewHostUniq();
|
||||||
extern void add_device(PPPoEDevice *device);
|
extern void add_device(PPPoEDevice *device);
|
||||||
extern void remove_device(PPPoEDevice *device);
|
extern void remove_device(PPPoEDevice *device);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// defined in PPPoEDevice.cpp
|
// defined in PPPoEDevice.cpp
|
||||||
extern void dump_packet(struct mbuf *packet);
|
extern void dump_packet(net_buffer *packet);
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,41 +3,57 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
|
#include <ethernet.h>
|
||||||
|
#include <ether_driver.h>
|
||||||
|
|
||||||
#include "PPPoEDevice.h"
|
#include "PPPoEDevice.h"
|
||||||
#include "DiscoveryPacket.h"
|
#include "DiscoveryPacket.h"
|
||||||
|
|
||||||
#include <core_funcs.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
// from libkernelppp
|
// from libkernelppp
|
||||||
#include <settings_tools.h>
|
#include <settings_tools.h>
|
||||||
|
|
||||||
|
extern net_stack_module_info *gStackModule;
|
||||||
|
extern net_buffer_module_info *gBufferModule;
|
||||||
|
extern status_t
|
||||||
|
pppoe_input(void *cookie, net_device *_device, net_buffer *packet);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
static char sDigits[] = "0123456789ABCDEF";
|
static char sDigits[] = "0123456789ABCDEF";
|
||||||
void
|
void
|
||||||
dump_packet(struct mbuf *packet)
|
dump_packet(net_buffer *packet)
|
||||||
{
|
{
|
||||||
if(!packet)
|
if (!packet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8 *data = mtod(packet, uint8*);
|
BufferHeaderReader<uint8> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return;
|
||||||
|
uint8 &buffer = bufferheader.Data();
|
||||||
|
uint8 *data = &buffer;
|
||||||
uint8 buffer[33];
|
uint8 buffer[33];
|
||||||
uint8 bufferIndex = 0;
|
uint8 bufferIndex = 0;
|
||||||
|
|
||||||
TRACE("Dumping packet;len=%ld;pkthdr.len=%d\n", packet->m_len,
|
TRACE("Dumping packet;len=%ld;pkthdr.len=%d\n", packet->m_len,
|
||||||
packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : -1);
|
packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : -1);
|
||||||
|
|
||||||
for(uint32 index = 0; index < packet->m_len; index++) {
|
for (uint32 index = 0; index < packet->m_len; index++) {
|
||||||
buffer[bufferIndex++] = sDigits[data[index] >> 4];
|
buffer[bufferIndex++] = sDigits[data[index] >> 4];
|
||||||
buffer[bufferIndex++] = sDigits[data[index] & 0x0F];
|
buffer[bufferIndex++] = sDigits[data[index] & 0x0F];
|
||||||
if(bufferIndex == 32 || index == packet->m_len - 1) {
|
if (bufferIndex == 32 || index == packet->m_len - 1) {
|
||||||
buffer[bufferIndex] = 0;
|
buffer[bufferIndex] = 0;
|
||||||
TRACE("%s\n", buffer);
|
TRACE("%s\n", buffer);
|
||||||
bufferIndex = 0;
|
bufferIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -54,30 +70,39 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
|
|||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
TRACE("PPPoEDevice: Constructor\n");
|
TRACE("PPPoEDevice: Constructor\n");
|
||||||
if(!settings || !settings->parameters)
|
if (!settings || !settings->parameters)
|
||||||
TRACE("PPPoEDevice::ctor: No settings!\n");
|
TRACE("PPPoEDevice::ctor: No settings!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
interface.SetPFCOptions(PPP_ALLOW_PFC);
|
interface.SetPFCOptions(PPP_ALLOW_PFC);
|
||||||
// we do not want to fail just because the other side requests PFC
|
// we do not want to fail just because the other side requests PFC
|
||||||
|
|
||||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||||
|
|
||||||
SetMTU(1494);
|
SetMTU(1494);
|
||||||
// MTU size does not contain PPP header
|
// MTU size does not contain PPP header
|
||||||
|
|
||||||
|
if (!settings)
|
||||||
|
dprintf("%s::%s: settings is NULL\n", __FILE__, __func__);
|
||||||
|
|
||||||
// find ethernet device
|
// find ethernet device
|
||||||
const char *interfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings);
|
finterfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings);
|
||||||
if(!interfaceName)
|
TRACE("%s::%s: finterfaceName is %s\n", __FILE__, __func__,
|
||||||
return;
|
finterfaceName ? finterfaceName : "NULL");
|
||||||
|
|
||||||
fACName = get_parameter_value(PPPoE_AC_NAME_KEY, settings);
|
fACName = get_parameter_value(PPPoE_AC_NAME_KEY, settings);
|
||||||
|
TRACE("fACName is %s\n", fACName ? fACName : "NULL");
|
||||||
|
|
||||||
fServiceName = get_parameter_value(PPPoE_SERVICE_NAME_KEY, settings);
|
fServiceName = get_parameter_value(PPPoE_SERVICE_NAME_KEY, settings);
|
||||||
|
TRACE("fServiceName is %s\n", fServiceName ? fServiceName : "NULL");
|
||||||
fEthernetIfnet = FindPPPoEInterface(interfaceName);
|
|
||||||
|
// fEthernetIfnet = FindPPPoEInterface(interfaceName);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if(!fEthernetIfnet)
|
if (!fEthernetIfnet)
|
||||||
TRACE("PPPoEDevice::ctor: could not find ethernet interface\n");
|
TRACE("PPPoEDevice::ctor: could not find ethernet interface\n");
|
||||||
|
else
|
||||||
|
TRACE("%s::%s: Find Ethernet device", __FILE__, __func__);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,8 +110,10 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
|
|||||||
status_t
|
status_t
|
||||||
PPPoEDevice::InitCheck() const
|
PPPoEDevice::InitCheck() const
|
||||||
{
|
{
|
||||||
return EthernetIfnet() && EthernetIfnet()->output
|
if (KPPPDevice::InitCheck() != B_OK)
|
||||||
&& KPPPDevice::InitCheck() == B_OK ? B_OK : B_ERROR;
|
dprintf("%s::%s: KPPPDevice::InitCheck() has error\n", __FILE__, __func__);
|
||||||
|
|
||||||
|
return KPPPDevice::InitCheck() == B_OK ? B_OK : B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -94,72 +121,103 @@ bool
|
|||||||
PPPoEDevice::Up()
|
PPPoEDevice::Up()
|
||||||
{
|
{
|
||||||
TRACE("PPPoEDevice: Up()\n");
|
TRACE("PPPoEDevice: Up()\n");
|
||||||
|
|
||||||
if(InitCheck() != B_OK)
|
if (InitCheck() != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(IsUp())
|
if (IsUp())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
fEthernetIfnet = FindPPPoEInterface(finterfaceName);
|
||||||
|
|
||||||
|
if (fEthernetIfnet == NULL) {
|
||||||
|
dprintf("%s::%s: fEthernetIfnet %s not found\n", __FILE__, __func__, finterfaceName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(fEtherAddr, fEthernetIfnet->address.data, ETHER_ADDRESS_LENGTH);
|
||||||
|
dprintf("ppp's corresponding addr is %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
|
fEtherAddr[0], fEtherAddr[1], fEtherAddr[2], fEtherAddr[3],
|
||||||
|
fEtherAddr[4], fEtherAddr[5]);
|
||||||
|
|
||||||
|
if (fEthernetIfnet->module == NULL) {
|
||||||
|
dprintf("%s::%s: fEthernetIfnet->module not found\n", __FILE__,
|
||||||
|
__func__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
add_device(this);
|
add_device(this);
|
||||||
|
|
||||||
fState = INITIAL;
|
fState = INITIAL;
|
||||||
// reset state
|
// reset state
|
||||||
|
|
||||||
if(fAttempts > PPPoE_MAX_ATTEMPTS) {
|
if (fAttempts > PPPoE_MAX_ATTEMPTS) {
|
||||||
fAttempts = 0;
|
fAttempts = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
++fAttempts;
|
++fAttempts;
|
||||||
// reset connection settings
|
// reset connection settings
|
||||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||||
|
|
||||||
// create PADI
|
// create PADI
|
||||||
DiscoveryPacket discovery(PADI);
|
DiscoveryPacket discovery(PADI);
|
||||||
if(ServiceName())
|
if (ServiceName())
|
||||||
discovery.AddTag(SERVICE_NAME, ServiceName(), strlen(ServiceName()));
|
discovery.AddTag(SERVICE_NAME, ServiceName(), strlen(ServiceName()));
|
||||||
else
|
else
|
||||||
discovery.AddTag(SERVICE_NAME, NULL, 0);
|
discovery.AddTag(SERVICE_NAME, NULL, 0);
|
||||||
discovery.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
|
discovery.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
|
||||||
discovery.AddTag(END_OF_LIST, NULL, 0);
|
discovery.AddTag(END_OF_LIST, NULL, 0);
|
||||||
|
|
||||||
// set up PPP header
|
// set up PPP header
|
||||||
struct mbuf *packet = discovery.ToMbuf(MTU());
|
net_buffer *packet = discovery.ToNetBuffer(MTU());
|
||||||
if(!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// create destination
|
// create ether header
|
||||||
struct ether_header *ethernetHeader;
|
NetBufferPrepend<ether_header> ethernetHeader(packet);
|
||||||
struct sockaddr destination;
|
if (ethernetHeader.Status() != B_OK)
|
||||||
memset(&destination, 0, sizeof(destination));
|
return false;
|
||||||
destination.sa_family = AF_UNSPEC;
|
ether_header &header = ethernetHeader.Data();
|
||||||
// raw packet with ethernet header
|
|
||||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
memset(header.destination, 0xff, ETHER_ADDRESS_LENGTH);
|
||||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
header.type = htons(ETHER_TYPE_PPPOE_DISCOVERY);
|
||||||
|
ethernetHeader.Sync();
|
||||||
|
// raw packet with ethernet header
|
||||||
|
|
||||||
// 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(fAttempts > 0 && !UpStarted()) {
|
if (fAttempts > 0 && !UpStarted()) {
|
||||||
fAttempts = 0;
|
fAttempts = 0;
|
||||||
remove_device(this);
|
remove_device(this);
|
||||||
DownEvent();
|
DownEvent();
|
||||||
return true;
|
return true;
|
||||||
// there was no error
|
// there was no error
|
||||||
}
|
}
|
||||||
|
|
||||||
fState = PADI_SENT;
|
fState = PADI_SENT;
|
||||||
// needed before sending, otherwise we might not get all packets
|
// needed before sending, otherwise we might not get all packets
|
||||||
|
|
||||||
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK) {
|
status_t status = gStackModule->register_device_handler(fEthernetIfnet,
|
||||||
|
B_NET_FRAME_TYPE_PPPOE_DISCOVERY, &pppoe_input, NULL);
|
||||||
|
if (status != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
status = gStackModule->register_device_handler(fEthernetIfnet,
|
||||||
|
B_NET_FRAME_TYPE_PPPOE, &pppoe_input, NULL);
|
||||||
|
if (status != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (EthernetIfnet()->module->send_data(EthernetIfnet(), packet) != B_OK) {
|
||||||
fState = INITIAL;
|
fState = INITIAL;
|
||||||
fAttempts = 0;
|
fAttempts = 0;
|
||||||
ERROR("PPPoEDevice::Up(): EthernetIfnet()->output() failed!\n");
|
ERROR("PPPoEDevice::Up(): EthernetIfnet()->output() failed!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dprintf("PPPoEDevice::Up(): EthernetIfnet()->output() success!\n");
|
||||||
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,36 +226,41 @@ bool
|
|||||||
PPPoEDevice::Down()
|
PPPoEDevice::Down()
|
||||||
{
|
{
|
||||||
TRACE("PPPoEDevice: Down()\n");
|
TRACE("PPPoEDevice: Down()\n");
|
||||||
|
|
||||||
|
gStackModule->unregister_device_handler(fEthernetIfnet,
|
||||||
|
B_NET_FRAME_TYPE_PPPOE_DISCOVERY);
|
||||||
|
gStackModule->unregister_device_handler(fEthernetIfnet,
|
||||||
|
B_NET_FRAME_TYPE_PPPOE);
|
||||||
|
|
||||||
remove_device(this);
|
remove_device(this);
|
||||||
|
|
||||||
if(InitCheck() != B_OK)
|
if (InitCheck() != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fState = INITIAL;
|
fState = INITIAL;
|
||||||
fAttempts = 0;
|
fAttempts = 0;
|
||||||
fNextTimeout = 0;
|
fNextTimeout = 0;
|
||||||
// disable timeouts
|
// disable timeouts
|
||||||
|
|
||||||
if(!IsUp()) {
|
if (!IsUp()) {
|
||||||
DownEvent();
|
DownEvent();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DownStarted();
|
DownStarted();
|
||||||
// this tells StateMachine that DownEvent() does not mean we lost connection
|
// 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, NULL, 0);
|
discovery.AddTag(END_OF_LIST, NULL, 0);
|
||||||
|
|
||||||
struct mbuf *packet = discovery.ToMbuf(MTU());
|
net_buffer *packet = discovery.ToNetBuffer(MTU());
|
||||||
if(!packet) {
|
if (!packet) {
|
||||||
ERROR("PPPoEDevice::Down(): ToMbuf() failed; MTU=%ld\n", MTU());
|
ERROR("PPPoEDevice::Down(): ToNetBuffer() failed; MTU=%ld\n", MTU());
|
||||||
DownEvent();
|
DownEvent();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create destination
|
// create destination
|
||||||
struct ether_header *ethernetHeader;
|
struct ether_header *ethernetHeader;
|
||||||
struct sockaddr destination;
|
struct sockaddr destination;
|
||||||
@@ -205,15 +268,15 @@ PPPoEDevice::Down()
|
|||||||
destination.sa_family = AF_UNSPEC;
|
destination.sa_family = AF_UNSPEC;
|
||||||
// raw packet with ethernet header
|
// raw packet with ethernet header
|
||||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
ethernetHeader->type = ETHER_TYPE_PPPOE_DISCOVERY;
|
||||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
memcpy(ethernetHeader->destination, fPeer, sizeof(fPeer));
|
||||||
|
|
||||||
// reset connection settings
|
// reset connection settings
|
||||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||||
|
|
||||||
EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL);
|
EthernetIfnet()->module->send_data(EthernetIfnet(), packet);
|
||||||
DownEvent();
|
DownEvent();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,220 +305,261 @@ PPPoEDevice::CountOutputBytes() const
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber)
|
PPPoEDevice::Send(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
// Send() is only for PPP packets. PPPoE packets are sent directly to ethernet.
|
// Send() is only for PPP packets. PPPoE packets are sent directly to ethernet.
|
||||||
|
|
||||||
TRACE("PPPoEDevice: Send()\n");
|
TRACE("PPPoEDevice: Send()\n");
|
||||||
|
|
||||||
if(!packet)
|
if (!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
else if(InitCheck() != B_OK || protocolNumber != 0) {
|
else if (InitCheck() != B_OK || protocolNumber != 0) {
|
||||||
ERROR("PPPoEDevice::Send(): InitCheck() != B_OK!\n");
|
ERROR("PPPoEDevice::Send(): InitCheck() != B_OK!\n");
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!IsUp()) {
|
if (!IsUp()) {
|
||||||
ERROR("PPPoEDevice::Send(): no connection!\n");
|
ERROR("PPPoEDevice::Send(): no connection!\n");
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return PPP_NO_CONNECTION;
|
return PPP_NO_CONNECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 length = packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : packet->m_len;
|
uint16 length = packet->size;
|
||||||
|
|
||||||
// encapsulate packet into pppoe header
|
// encapsulate packet into pppoe header
|
||||||
M_PREPEND(packet, PPPoE_HEADER_SIZE);
|
NetBufferPrepend<pppoe_header> bufferheader(packet);
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
if (bufferheader.Status() != B_OK)
|
||||||
header->version = PPPoE_VERSION;
|
return B_ERROR;
|
||||||
header->type = PPPoE_TYPE;
|
pppoe_header &header = bufferheader.Data();
|
||||||
header->code = 0x00;
|
header.version = PPPoE_VERSION;
|
||||||
header->sessionID = SessionID();
|
header.type = PPPoE_TYPE;
|
||||||
header->length = htons(length);
|
header.code = 0x00;
|
||||||
|
header.sessionID = SessionID();
|
||||||
// create destination
|
header.length = htons(length);
|
||||||
struct ether_header *ethernetHeader;
|
bufferheader.Sync();
|
||||||
struct sockaddr destination;
|
|
||||||
memset(&destination, 0, sizeof(destination));
|
// create ether header
|
||||||
destination.sa_family = AF_UNSPEC;
|
NetBufferPrepend<ether_header> ethernetHeader(packet);
|
||||||
// raw packet with ethernet header
|
if (ethernetHeader.Status() != B_OK)
|
||||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
return false;
|
||||||
ethernetHeader->ether_type = ETHERTYPE_PPPOE;
|
ether_header ðheader = ethernetHeader.Data();
|
||||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
|
||||||
|
memcpy(ethheader.destination, fPeer, ETHER_ADDRESS_LENGTH);
|
||||||
if(!packet || !mtod(packet, pppoe_header*))
|
memcpy(ethheader.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||||
|
ethheader.type = htons(ETHER_TYPE_PPPOE);
|
||||||
|
ethernetHeader.Sync();
|
||||||
|
// raw packet with ethernet header
|
||||||
|
|
||||||
|
if (!packet)
|
||||||
ERROR("PPPoEDevice::Send(): packet is NULL!\n");
|
ERROR("PPPoEDevice::Send(): packet is NULL!\n");
|
||||||
|
|
||||||
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK) {
|
if (EthernetIfnet()->module->send_data(EthernetIfnet(), packet) != B_OK) {
|
||||||
ERROR("PPPoEDevice::Send(): EthernetIfnet()->output() failed!\n");
|
ERROR("PPPoEDevice::Send(): EthernetIfnet()->output() failed!\n");
|
||||||
remove_device(this);
|
remove_device(this);
|
||||||
DownEvent();
|
DownEvent();
|
||||||
// DownEvent() without DownStarted() indicates connection lost
|
// DownEvent() without DownStarted() indicates connection lost
|
||||||
return PPP_NO_CONNECTION;
|
return PPP_NO_CONNECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
PPPoEDevice::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
if(!packet)
|
TRACE("%s entering %s: protocolNumber:%x\n", __FILE__, __func__, protocolNumber);
|
||||||
|
if (!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
else if(InitCheck() != B_OK || IsDown()) {
|
|
||||||
m_freem(packet);
|
if (InitCheck() != B_OK || IsDown()) {
|
||||||
|
dprintf("PPPoED InitCheck fail or IsDown\n");
|
||||||
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive fail\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
complete_pppoe_header *completeHeader = mtod(packet, complete_pppoe_header*);
|
|
||||||
if(!completeHeader) {
|
|
||||||
m_freem(packet);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 ethernetSource[6];
|
uint8 ethernetSource[6];
|
||||||
memcpy(ethernetSource, completeHeader->ethernetHeader.ether_shost, sizeof(fPeer));
|
struct sockaddr_dl& source = *(struct sockaddr_dl*)packet->source;
|
||||||
status_t result = B_OK;
|
memcpy(ethernetSource, source.sdl_data, sizeof(fPeer));
|
||||||
|
|
||||||
if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOE) {
|
int32 PPP_Packet_Type = B_NET_FRAME_TYPE(source.sdl_type,
|
||||||
m_adj(packet, ETHER_HDR_LEN);
|
ntohs(source.sdl_e_type));
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
// bufferheader.Remove();
|
||||||
|
// bufferheader.Sync();
|
||||||
if(!IsUp() || header->version != PPPoE_VERSION || header->type != PPPoE_TYPE
|
|
||||||
|| header->code != 0x0 || header->sessionID != SessionID()) {
|
if (PPP_Packet_Type == B_NET_FRAME_TYPE_PPPOE) {
|
||||||
m_freem(packet);
|
TRACE("ETHER_TYPE_PPPOE\n");
|
||||||
|
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK) {
|
||||||
|
TRACE("creat NetBufferHeaderReader fail\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
pppoe_header &header = bufferheader.Data();
|
||||||
m_adj(packet, PPPoE_HEADER_SIZE);
|
uint16 ppppoe_payload = ntohs(header.length);
|
||||||
|
|
||||||
|
if (!IsUp() || header.version != PPPoE_VERSION || header.type != PPPoE_TYPE
|
||||||
|
|| header.code != 0x0 || header.sessionID != SessionID()) {
|
||||||
|
// gBufferModule->free(packet);
|
||||||
|
TRACE("basic pppoe header check fail\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferheader.Remove();
|
||||||
|
bufferheader.Sync();
|
||||||
|
|
||||||
|
// trim the packet according to actual pppoe_payload
|
||||||
|
gBufferModule->trim(packet, ppppoe_payload);
|
||||||
|
|
||||||
return Interface().ReceiveFromDevice(packet);
|
return Interface().ReceiveFromDevice(packet);
|
||||||
} else if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC) {
|
}
|
||||||
m_adj(packet, ETHER_HDR_LEN);
|
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
if (PPP_Packet_Type == B_NET_FRAME_TYPE_PPPOE_DISCOVERY) {
|
||||||
|
dprintf("ETHER_TYPE_PPPOE_DISCOVERY\n");
|
||||||
|
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK) {
|
||||||
|
dprintf("create NetBufferHeaderReader fail\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
pppoe_header &header = bufferheader.Data();
|
||||||
|
|
||||||
// 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);
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive fail version type wrong\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsDown()) {
|
if (IsDown()) {
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive fail PPPoEDev IsDown\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscoveryPacket discovery(packet);
|
DiscoveryPacket discovery(packet);
|
||||||
switch(discovery.Code()) {
|
switch(discovery.Code()) {
|
||||||
case PADO: {
|
case PADO: {
|
||||||
if(fState != PADI_SENT) {
|
dprintf("processing PADO\n");
|
||||||
m_freem(packet);
|
if (fState != PADI_SENT) {
|
||||||
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive faile not PADI_Sent \n");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasServiceName = false, hasACName = false;
|
bool hasServiceName = false, hasACName = false;
|
||||||
pppoe_tag *tag;
|
pppoe_tag *tag;
|
||||||
DiscoveryPacket reply(PADR);
|
DiscoveryPacket reply(PADR);
|
||||||
for(int32 index = 0; index < discovery.CountTags(); index++) {
|
for (int32 index = 0; index < discovery.CountTags(); index++) {
|
||||||
tag = discovery.TagAt(index);
|
tag = discovery.TagAt(index);
|
||||||
if(!tag)
|
if (!tag)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch(tag->type) {
|
switch (tag->type) {
|
||||||
case SERVICE_NAME:
|
case SERVICE_NAME:
|
||||||
if(!hasServiceName && (!ServiceName()
|
if (!hasServiceName && (!ServiceName()
|
||||||
|| (strlen(ServiceName()) == tag->length)
|
|| ((strlen(ServiceName()) == tag->length)
|
||||||
&& !memcmp(tag->data, ServiceName(),
|
&& !memcmp(tag->data, ServiceName(),
|
||||||
tag->length))) {
|
tag->length)))) {
|
||||||
hasServiceName = true;
|
hasServiceName = true;
|
||||||
reply.AddTag(tag->type, tag->data, tag->length);
|
reply.AddTag(tag->type, tag->data, tag->length);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AC_NAME:
|
case AC_NAME:
|
||||||
if(!hasACName && (!ACName()
|
if (!hasACName && (!ACName()
|
||||||
|| (strlen(ACName()) == tag->length)
|
|| ((strlen(ACName()) == tag->length)
|
||||||
&& !memcmp(tag->data, ACName(),
|
&& !memcmp(tag->data, ACName(),
|
||||||
tag->length))) {
|
tag->length)))) {
|
||||||
hasACName = true;
|
hasACName = true;
|
||||||
reply.AddTag(tag->type, tag->data, tag->length);
|
reply.AddTag(tag->type, tag->data, tag->length);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AC_COOKIE:
|
case AC_COOKIE:
|
||||||
case RELAY_SESSION_ID:
|
case RELAY_SESSION_ID:
|
||||||
reply.AddTag(tag->type, tag->data, tag->length);
|
reply.AddTag(tag->type, tag->data, tag->length);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_NAME_ERROR:
|
case SERVICE_NAME_ERROR:
|
||||||
case AC_SYSTEM_ERROR:
|
case AC_SYSTEM_ERROR:
|
||||||
case GENERIC_ERROR:
|
case GENERIC_ERROR:
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::generic error faile\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!hasServiceName) {
|
if (!hasServiceName) {
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive faile no svc name\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dprintf("reply.AddTag\n");
|
||||||
reply.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
|
reply.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
|
||||||
reply.AddTag(END_OF_LIST, NULL, 0);
|
reply.AddTag(END_OF_LIST, NULL, 0);
|
||||||
struct mbuf *replyPacket = reply.ToMbuf(MTU());
|
net_buffer *replyPacket = reply.ToNetBuffer(MTU());
|
||||||
if(!replyPacket) {
|
if (!replyPacket) {
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive fail no reply pack\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(fPeer, ethernetSource, sizeof(fPeer));
|
memcpy(fPeer, ethernetSource, ETHER_ADDRESS_LENGTH);
|
||||||
|
|
||||||
// create destination
|
// create ether header
|
||||||
struct ether_header *ethernetHeader;
|
NetBufferPrepend<ether_header> ethernetHeader(replyPacket);
|
||||||
struct sockaddr destination;
|
if (ethernetHeader.Status() != B_OK)
|
||||||
memset(&destination, 0, sizeof(destination));
|
return false;
|
||||||
destination.sa_family = AF_UNSPEC;
|
ether_header &header = ethernetHeader.Data();
|
||||||
// raw packet with ethernet header
|
|
||||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
memcpy(header.destination, fPeer, ETHER_ADDRESS_LENGTH);
|
||||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
header.type=htons(ETHER_TYPE_PPPOE_DISCOVERY);
|
||||||
|
ethernetHeader.Sync();
|
||||||
|
// raw packet with ethernet header
|
||||||
|
|
||||||
fState = PADR_SENT;
|
fState = PADR_SENT;
|
||||||
|
|
||||||
if(EthernetIfnet()->output(EthernetIfnet(), replyPacket, &destination,
|
if (EthernetIfnet()->module->send_data(EthernetIfnet(), replyPacket) != B_OK) {
|
||||||
NULL) != B_OK) {
|
gBufferModule->free(replyPacket);
|
||||||
m_freem(packet);
|
dprintf("PPPoEDevice::Receive fail send PADR\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
case PADS:
|
case PADS:
|
||||||
if(fState != PADR_SENT
|
dprintf("procesing PADS\n");
|
||||||
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
|
if (fState != PADR_SENT
|
||||||
m_freem(packet);
|
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
|
||||||
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive PADS but no PADR sent\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fSessionID = header->sessionID;
|
fSessionID = header.sessionID;
|
||||||
fState = OPENED;
|
fState = OPENED;
|
||||||
fNextTimeout = 0;
|
fNextTimeout = 0;
|
||||||
UpEvent();
|
UpEvent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PADT:
|
case PADT:
|
||||||
if(!IsUp()
|
dprintf("procesing PADT\n");
|
||||||
|
if (!IsUp()
|
||||||
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))
|
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))
|
||||||
|| header->sessionID != SessionID()) {
|
|| header.sessionID != SessionID()) {
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive fail not up yet\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fState = INITIAL;
|
fState = INITIAL;
|
||||||
fAttempts = 0;
|
fAttempts = 0;
|
||||||
fSessionID = 0;
|
fSessionID = 0;
|
||||||
@@ -463,16 +567,17 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
remove_device(this);
|
remove_device(this);
|
||||||
DownEvent();
|
DownEvent();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
m_freem(packet);
|
dprintf("PPPoEDevice::Receive fail unknown pppoed code\n");
|
||||||
|
// gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
result = B_ERROR;
|
|
||||||
|
dprintf("PPPoEDevice::Receive PADX fine!\n");
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
return result;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -480,13 +585,12 @@ void
|
|||||||
PPPoEDevice::Pulse()
|
PPPoEDevice::Pulse()
|
||||||
{
|
{
|
||||||
// We use Pulse() for timeout of connection establishment.
|
// We use Pulse() for timeout of connection establishment.
|
||||||
|
if (fNextTimeout == 0 || IsUp() || IsDown())
|
||||||
if(fNextTimeout == 0 || IsUp() || IsDown())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// check if timed out
|
// check if timed out
|
||||||
if(system_time() >= fNextTimeout) {
|
if (system_time() >= fNextTimeout) {
|
||||||
if(!Up())
|
if (!Up())
|
||||||
UpFailedEvent();
|
UpFailedEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
|
|
||||||
#include <KPPPDevice.h>
|
#include <KPPPDevice.h>
|
||||||
|
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
|
|
||||||
enum pppoe_state {
|
enum pppoe_state {
|
||||||
INITIAL,
|
INITIAL,
|
||||||
@@ -25,7 +28,7 @@ class PPPoEDevice : public KPPPDevice {
|
|||||||
public:
|
public:
|
||||||
PPPoEDevice(KPPPInterface& interface, driver_parameter *settings);
|
PPPoEDevice(KPPPInterface& interface, driver_parameter *settings);
|
||||||
|
|
||||||
ifnet *EthernetIfnet() const
|
net_device *EthernetIfnet() const
|
||||||
{ return fEthernetIfnet; }
|
{ return fEthernetIfnet; }
|
||||||
|
|
||||||
const uint8 *Peer() const
|
const uint8 *Peer() const
|
||||||
@@ -50,17 +53,19 @@ class PPPoEDevice : public KPPPDevice {
|
|||||||
|
|
||||||
virtual uint32 CountOutputBytes() const;
|
virtual uint32 CountOutputBytes() const;
|
||||||
|
|
||||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber = 0);
|
virtual status_t Send(net_buffer *packet, uint16 protocolNumber = 0);
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber = 0);
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber = 0);
|
||||||
|
|
||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ifnet *fEthernetIfnet;
|
net_device *fEthernetIfnet;
|
||||||
uint8 fPeer[6];
|
uint8 fPeer[6];
|
||||||
|
uint8 fEtherAddr[6];
|
||||||
uint16 fSessionID;
|
uint16 fSessionID;
|
||||||
uint32 fHostUniq;
|
uint32 fHostUniq;
|
||||||
const char *fACName, *fServiceName;
|
const char *fACName, *fServiceName;
|
||||||
|
const char *finterfaceName;
|
||||||
|
|
||||||
uint32 fAttempts;
|
uint32 fAttempts;
|
||||||
bigtime_t fNextTimeout;
|
bigtime_t fNextTimeout;
|
||||||
|
|||||||
@@ -5,34 +5,46 @@
|
|||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
#include <net_module.h>
|
|
||||||
|
|
||||||
#include <ethernet_module.h>
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_datalink.h> // for get_interface and control
|
||||||
|
#include <net_stack.h>
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
|
||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
#include <KPPPModule.h>
|
#include <KPPPModule.h>
|
||||||
#include <KPPPUtils.h>
|
#include <KPPPUtils.h>
|
||||||
#include <LockerHelper.h>
|
|
||||||
|
|
||||||
#include "PPPoEDevice.h"
|
#include "PPPoEDevice.h"
|
||||||
#include "DiscoveryPacket.h"
|
#include "DiscoveryPacket.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct pppoe_query {
|
typedef struct pppoe_query {
|
||||||
ifnet *ethernetIfnet;
|
net_device *ethernetIfnet;
|
||||||
uint32 hostUniq;
|
uint32 hostUniq;
|
||||||
thread_id receiver;
|
thread_id receiver;
|
||||||
} pppoe_query;
|
} pppoe_query;
|
||||||
|
|
||||||
#define PPPoE_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pppoe"
|
#define PPPoE_MODULE_NAME "network/ppp/pppoe"
|
||||||
|
|
||||||
|
net_stack_module_info *gStackModule = NULL;
|
||||||
|
net_buffer_module_info *gBufferModule = NULL;
|
||||||
|
net_datalink_module_info *sDatalinkModule = NULL;
|
||||||
|
|
||||||
struct core_module_info *core = NULL;
|
|
||||||
static struct ethernet_module_info *sEthernet;
|
|
||||||
static int32 sHostUniq = 0;
|
static int32 sHostUniq = 0;
|
||||||
status_t std_ops(int32 op, ...);
|
status_t std_ops(int32 op, ...);
|
||||||
|
|
||||||
static BLocker sLock("PPPoEList");
|
// static mutex sLock("PPPoEList");
|
||||||
|
|
||||||
static TemplateList<PPPoEDevice*> *sDevices;
|
static TemplateList<PPPoEDevice*> *sDevices;
|
||||||
static TemplateList<pppoe_query*> *sQueries;
|
static TemplateList<pppoe_query*> *sQueries;
|
||||||
|
|
||||||
@@ -44,51 +56,75 @@ SendQueryPacket(pppoe_query *query, DiscoveryPacket& discovery)
|
|||||||
char data[PPPoE_QUERY_REPORT_SIZE];
|
char data[PPPoE_QUERY_REPORT_SIZE];
|
||||||
uint32 position = sizeof(uint32);
|
uint32 position = sizeof(uint32);
|
||||||
pppoe_tag *acName = discovery.TagWithType(AC_NAME);
|
pppoe_tag *acName = discovery.TagWithType(AC_NAME);
|
||||||
|
|
||||||
if(acName) {
|
if (acName) {
|
||||||
if(acName->length >= PPPoE_QUERY_REPORT_SIZE)
|
if (acName->length >= PPPoE_QUERY_REPORT_SIZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(data + position, acName->data, acName->length);
|
memcpy(data + position, acName->data, acName->length);
|
||||||
position += acName->length;
|
position += acName->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
data[position++] = 0;
|
data[position++] = 0;
|
||||||
|
|
||||||
pppoe_tag *tag;
|
pppoe_tag *tag;
|
||||||
for(int32 index = 0; index < discovery.CountTags(); index++) {
|
for (int32 index = 0; index < discovery.CountTags(); index++) {
|
||||||
tag = discovery.TagAt(index);
|
tag = discovery.TagAt(index);
|
||||||
if(tag && tag->type == SERVICE_NAME) {
|
if (tag && tag->type == SERVICE_NAME) {
|
||||||
if(position + tag->length >= PPPoE_QUERY_REPORT_SIZE)
|
if (position + tag->length >= PPPoE_QUERY_REPORT_SIZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(data + position, tag->data, tag->length);
|
memcpy(data + position, tag->data, tag->length);
|
||||||
position += tag->length;
|
position += tag->length;
|
||||||
data[position++] = 0;
|
data[position++] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data, &position, sizeof(uint32));
|
memcpy(data, &position, sizeof(uint32));
|
||||||
// add the total length
|
// add the total length
|
||||||
|
|
||||||
send_data_with_timeout(query->receiver, PPPoE_QUERY_REPORT, data,
|
send_data_with_timeout(query->receiver, PPPoE_QUERY_REPORT, data,
|
||||||
PPPoE_QUERY_REPORT_SIZE, 700000);
|
PPPoE_QUERY_REPORT_SIZE, 700000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ifnet*
|
net_interface *
|
||||||
|
get_interface_by_name(net_domain *domain, const char *name)
|
||||||
|
{
|
||||||
|
ifreq request;
|
||||||
|
memset(&request, 0, sizeof(request));
|
||||||
|
size_t size = sizeof(request);
|
||||||
|
|
||||||
|
strlcpy(request.ifr_name, name, IF_NAMESIZE);
|
||||||
|
|
||||||
|
if (sDatalinkModule->control(domain, SIOCGIFINDEX, &request, &size) != B_OK) {
|
||||||
|
TRACE("sDatalinkModule->control failure\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return sDatalinkModule->get_interface(domain, request.ifr_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
net_device*
|
||||||
FindPPPoEInterface(const char *name)
|
FindPPPoEInterface(const char *name)
|
||||||
{
|
{
|
||||||
if(!name)
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
net_interface* ethernetInterfaceOfPPPOE = NULL;
|
||||||
|
net_domain* domain = NULL;
|
||||||
|
|
||||||
|
domain = gStackModule->get_domain(AF_INET);
|
||||||
|
ethernetInterfaceOfPPPOE = get_interface_by_name(domain, name);
|
||||||
|
|
||||||
|
if (ethernetInterfaceOfPPPOE == NULL) {
|
||||||
|
TRACE("get_interface_by_name can not find eth\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ifnet *current = get_interfaces();
|
|
||||||
for(; current; current = current->if_next) {
|
|
||||||
if(current->if_type == IFT_ETHER && current->if_name
|
|
||||||
&& !strcmp(current->if_name, name))
|
|
||||||
return current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ethernetInterfaceOfPPPOE->device)
|
||||||
|
return ethernetInterfaceOfPPPOE->device;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,9 +140,9 @@ void
|
|||||||
add_device(PPPoEDevice *device)
|
add_device(PPPoEDevice *device)
|
||||||
{
|
{
|
||||||
TRACE("PPPoE: add_device()\n");
|
TRACE("PPPoE: add_device()\n");
|
||||||
|
|
||||||
LockerHelper locker(sLock);
|
// MutexLocker locker(sLock);
|
||||||
if(!sDevices->HasItem(device))
|
if (!sDevices->HasItem(device))
|
||||||
sDevices->AddItem(device);
|
sDevices->AddItem(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,85 +151,125 @@ void
|
|||||||
remove_device(PPPoEDevice *device)
|
remove_device(PPPoEDevice *device)
|
||||||
{
|
{
|
||||||
TRACE("PPPoE: remove_device()\n");
|
TRACE("PPPoE: remove_device()\n");
|
||||||
|
|
||||||
LockerHelper locker(sLock);
|
// MutexLocker locker(sLock);
|
||||||
sDevices->RemoveItem(device);
|
sDevices->RemoveItem(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
status_t
|
||||||
void
|
pppoe_input(void *cookie, net_device *_device, net_buffer *packet)
|
||||||
pppoe_input(struct mbuf *packet)
|
|
||||||
{
|
{
|
||||||
if(!packet)
|
if (!packet)
|
||||||
return;
|
return B_ERROR;
|
||||||
|
|
||||||
ifnet *sourceIfnet = packet->m_pkthdr.rcvif;
|
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||||
complete_pppoe_header *header = mtod(packet, complete_pppoe_header*);
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
pppoe_header &header = bufferheader.Data();
|
||||||
|
|
||||||
|
// remove the following lines when pppoe server is enabled
|
||||||
|
if (header.code == PADI) {
|
||||||
|
TRACE("PADI packet received, ignoreing!\n");
|
||||||
|
gBufferModule->free(packet);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.code == PADO || header.code == PADR || header.code == PADS || header.code == PADT)
|
||||||
|
{
|
||||||
|
uint8 peerEtherAddr[ETHER_ADDRESS_LENGTH];
|
||||||
|
struct sockaddr_dl& source = *(struct sockaddr_dl*)packet->source;
|
||||||
|
memcpy(peerEtherAddr, source.sdl_data, ETHER_ADDRESS_LENGTH);
|
||||||
|
const char *str = header.code == PADI ? "PADI" :
|
||||||
|
header.code == PADO ? "PADO" :
|
||||||
|
header.code == PADR ? "PADR" :
|
||||||
|
header.code == PADS ? "PADS" :
|
||||||
|
"PADT" ;
|
||||||
|
|
||||||
|
dprintf("%s from:%02x:%02x:%02x:%02x:%02x:%02x code:%02x\n", str,
|
||||||
|
peerEtherAddr[0], peerEtherAddr[1], peerEtherAddr[2],
|
||||||
|
peerEtherAddr[3], peerEtherAddr[4], peerEtherAddr[5],
|
||||||
|
header.code);
|
||||||
|
}
|
||||||
|
|
||||||
PPPoEDevice *device;
|
PPPoEDevice *device;
|
||||||
pppoe_query *query;
|
pppoe_query *query;
|
||||||
|
|
||||||
LockerHelper locker(sLock);
|
sockaddr_dl& linkAddress = *(sockaddr_dl*)packet->source;
|
||||||
|
int32 specificType = B_NET_FRAME_TYPE(linkAddress.sdl_type,
|
||||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC
|
ntohs(linkAddress.sdl_e_type));
|
||||||
&& header->pppoeHeader.length <= PPPoE_QUERY_REPORT_SIZE) {
|
|
||||||
for(int32 index = 0; index < sDevices->CountItems(); index++) {
|
// MutexLocker locker(sLock);
|
||||||
|
|
||||||
|
if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
|
||||||
|
&& ntohs(header.length) <= PPPoE_QUERY_REPORT_SIZE) {
|
||||||
|
for (int32 index = 0; index < sDevices->CountItems(); index++) {
|
||||||
query = sQueries->ItemAt(index);
|
query = sQueries->ItemAt(index);
|
||||||
|
|
||||||
if(query && query->ethernetIfnet == sourceIfnet) {
|
if (query) {// && query->ethernetIfnet == sourceIfnet) {
|
||||||
if(header->pppoeHeader.code == PADO) {
|
if (header.code == PADO) {
|
||||||
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||||
if(discovery.InitCheck() != B_OK) {
|
if (discovery.InitCheck() != B_OK) {
|
||||||
ERROR("PPPoE: received corrupted discovery packet!\n");
|
ERROR("PPPoE: received corrupted discovery packet!\n");
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
return;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pppoe_tag *hostTag = discovery.TagWithType(HOST_UNIQ);
|
pppoe_tag *hostTag = discovery.TagWithType(HOST_UNIQ);
|
||||||
if(hostTag && hostTag->length == 4
|
if (hostTag && hostTag->length == 4
|
||||||
&& *((uint32*)hostTag->data) == query->hostUniq) {
|
&& *((uint32*)hostTag->data) == query->hostUniq) {
|
||||||
SendQueryPacket(query, discovery);
|
SendQueryPacket(query, discovery);
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
return;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int32 index = 0; index < sDevices->CountItems(); index++) {
|
TRACE("in pppoed processing sDevices->CountItems(): %ld\n", sDevices->CountItems());
|
||||||
|
|
||||||
|
for (int32 index = 0; index < sDevices->CountItems(); index++) {
|
||||||
device = sDevices->ItemAt(index);
|
device = sDevices->ItemAt(index);
|
||||||
|
|
||||||
if(device && device->EthernetIfnet() == sourceIfnet) {
|
TRACE("device->SessionID() %d, header.sessionID: %d\n", device->SessionID(),
|
||||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE
|
header.sessionID);
|
||||||
&& header->pppoeHeader.sessionID == device->SessionID()) {
|
|
||||||
|
if (device) { // && device->EthernetIfnet() == sourceIfnet) {
|
||||||
|
if (specificType == B_NET_FRAME_TYPE_PPPOE
|
||||||
|
&& header.sessionID == device->SessionID()) {
|
||||||
TRACE("PPPoE: session packet\n");
|
TRACE("PPPoE: session packet\n");
|
||||||
device->Receive(packet);
|
device->Receive(packet);
|
||||||
return;
|
return B_OK;
|
||||||
} else if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC
|
}
|
||||||
&& header->pppoeHeader.code != PADI
|
|
||||||
&& header->pppoeHeader.code != PADR
|
if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
|
||||||
|
&& header.code != PADI
|
||||||
|
&& header.code != PADR
|
||||||
&& !device->IsDown()) {
|
&& !device->IsDown()) {
|
||||||
TRACE("PPPoE: discovery packet\n");
|
TRACE("PPPoE: discovery packet\n");
|
||||||
|
|
||||||
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||||
if(discovery.InitCheck() != B_OK) {
|
if (discovery.InitCheck() != B_OK) {
|
||||||
ERROR("PPPoE: received corrupted discovery packet!\n");
|
ERROR("PPPoE: received corrupted discovery packet!\n");
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ);
|
pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ);
|
||||||
if(header->pppoeHeader.code == PADT || (tag && tag->length == 4
|
if (header.code == PADT || (tag && tag->length == 4
|
||||||
&& *((uint32*)tag->data) == device->HostUniq())) {
|
&& *((uint32*)tag->data) == device->HostUniq())) {
|
||||||
device->Receive(packet);
|
device->Receive(packet);
|
||||||
return;
|
return B_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ERROR("PPPoE: No device found for packet from: %s\n", sourceIfnet->if_name);
|
ERROR("PPPoE: No device found for packet from: %s\n", "ethernet");
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -202,22 +278,22 @@ bool
|
|||||||
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
||||||
driver_parameter *settings, ppp_module_key_type type)
|
driver_parameter *settings, ppp_module_key_type type)
|
||||||
{
|
{
|
||||||
if(mainInterface.Mode() != PPP_CLIENT_MODE || type != PPP_DEVICE_KEY_TYPE)
|
if (mainInterface.Mode() != PPP_CLIENT_MODE || type != PPP_DEVICE_KEY_TYPE)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
PPPoEDevice *device;
|
PPPoEDevice *device;
|
||||||
bool success;
|
bool success;
|
||||||
if(subInterface) {
|
if (subInterface) {
|
||||||
device = new PPPoEDevice(*subInterface, settings);
|
device = new PPPoEDevice(*subInterface, settings);
|
||||||
success = subInterface->SetDevice(device);
|
success = subInterface->SetDevice(device);
|
||||||
} else {
|
} else {
|
||||||
device = new PPPoEDevice(mainInterface, settings);
|
device = new PPPoEDevice(mainInterface, settings);
|
||||||
success = mainInterface.SetDevice(device);
|
success = mainInterface.SetDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("PPPoE: add_to(): %s\n",
|
TRACE("PPPoE: add_to(): %s\n",
|
||||||
success && device && device->InitCheck() == B_OK ? "OK" : "ERROR");
|
success && device && device->InitCheck() == B_OK ? "OK" : "ERROR");
|
||||||
|
|
||||||
return success && device && device->InitCheck() == B_OK;
|
return success && device && device->InitCheck() == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,59 +302,62 @@ static
|
|||||||
status_t
|
status_t
|
||||||
control(uint32 op, void *data, size_t length)
|
control(uint32 op, void *data, size_t length)
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch (op) {
|
||||||
case PPPoE_GET_INTERFACES: {
|
case PPPoE_GET_INTERFACES: {
|
||||||
int32 position = 0, count = 0;
|
int32 position = 0, count = 0;
|
||||||
char *names = (char*) data;
|
char *names = (char*) data;
|
||||||
|
|
||||||
ifnet *current = get_interfaces();
|
net_device *current = NULL; // get_interfaces();
|
||||||
for(; current; current = current->if_next) {
|
for (; current; current = NULL) {
|
||||||
if(current->if_type == IFT_ETHER && current->if_name) {
|
if (current->type == IFT_ETHER && current->name) {
|
||||||
if(position + strlen(current->if_name) + 1 > length)
|
if (position + strlen(current->name) + 1 > length)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
strcpy(names + position, current->if_name);
|
strcpy(names + position, current->name);
|
||||||
position += strlen(current->if_name);
|
position += strlen(current->name);
|
||||||
names[position++] = 0;
|
names[position++] = 0;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PPPoE_QUERY_SERVICES: {
|
case PPPoE_QUERY_SERVICES: {
|
||||||
// XXX: as all modules are loaded on-demand we must wait for the results
|
// XXX: as all modules are loaded on-demand we must wait for the results
|
||||||
|
|
||||||
if(!data || length != sizeof(pppoe_query_request))
|
if (!data || length != sizeof(pppoe_query_request))
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
pppoe_query_request *request = (pppoe_query_request*) data;
|
pppoe_query_request *request = (pppoe_query_request*) data;
|
||||||
|
|
||||||
pppoe_query query;
|
pppoe_query query;
|
||||||
query.ethernetIfnet = FindPPPoEInterface(request->interfaceName);
|
query.ethernetIfnet = FindPPPoEInterface(request->interfaceName);
|
||||||
if(!query.ethernetIfnet)
|
if (!query.ethernetIfnet)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
query.hostUniq = NewHostUniq();
|
query.hostUniq = NewHostUniq();
|
||||||
query.receiver = request->receiver;
|
query.receiver = request->receiver;
|
||||||
|
|
||||||
sLock.Lock();
|
{
|
||||||
sQueries->AddItem(&query);
|
// MutexLocker tlocker(sLock);
|
||||||
sLock.Unlock();
|
TRACE("add query\n");
|
||||||
|
sQueries->AddItem(&query);
|
||||||
|
}
|
||||||
|
|
||||||
snooze(2000000);
|
snooze(2000000);
|
||||||
// wait two seconds for results
|
// wait two seconds for results
|
||||||
|
{
|
||||||
sLock.Lock();
|
// MutexLocker tlocker(sLock);
|
||||||
sQueries->RemoveItem(&query);
|
TRACE("remove query\n");
|
||||||
sLock.Unlock();
|
sQueries->RemoveItem(&query);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,40 +375,48 @@ static ppp_module_info pppoe_module = {
|
|||||||
|
|
||||||
_EXPORT
|
_EXPORT
|
||||||
status_t
|
status_t
|
||||||
std_ops(int32 op, ...)
|
std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case B_MODULE_INIT:
|
case B_MODULE_INIT:
|
||||||
if(get_module(NET_CORE_MODULE_NAME, (module_info**)&core) != B_OK)
|
if (get_module(NET_STACK_MODULE_NAME,
|
||||||
|
(module_info**)&gStackModule) != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if(get_module(NET_ETHERNET_MODULE_NAME,
|
if (get_module(NET_DATALINK_MODULE_NAME,
|
||||||
(module_info**) &sEthernet) != B_OK) {
|
(module_info **)&sDatalinkModule) != B_OK) {
|
||||||
put_module(NET_CORE_MODULE_NAME);
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_max_linkhdr(2 + PPPoE_HEADER_SIZE + ETHER_HDR_LEN);
|
if (get_module(NET_BUFFER_MODULE_NAME,
|
||||||
|
(module_info **)&gBufferModule) != B_OK) {
|
||||||
|
put_module(NET_DATALINK_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set_max_linkhdr(2 + PPPoE_HEADER_SIZE + ETHER_HDR_LEN);
|
||||||
// 2 bytes for PPP header
|
// 2 bytes for PPP header
|
||||||
sDevices = new TemplateList<PPPoEDevice*>;
|
sDevices = new TemplateList<PPPoEDevice*>;
|
||||||
sQueries = new TemplateList<pppoe_query*>;
|
sQueries = new TemplateList<pppoe_query*>;
|
||||||
sEthernet->set_pppoe_receiver(pppoe_input);
|
|
||||||
|
|
||||||
TRACE("PPPoE: Registered PPPoE receiver.\n");
|
TRACE("PPPoE: Registered PPPoE receiver.\n");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
case B_MODULE_UNINIT:
|
case B_MODULE_UNINIT:
|
||||||
|
delete sQueries;
|
||||||
delete sDevices;
|
delete sDevices;
|
||||||
sEthernet->unset_pppoe_receiver();
|
|
||||||
TRACE("PPPoE: Unregistered PPPoE receiver.\n");
|
TRACE("PPPoE: Unregistered PPPoE receiver.\n");
|
||||||
put_module(NET_CORE_MODULE_NAME);
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
put_module(NET_ETHERNET_MODULE_NAME);
|
put_module(NET_DATALINK_MODULE_NAME);
|
||||||
break;
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ if $(TARGET_PLATFORM) != haiku {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
|
UsePrivateHeaders net ;
|
||||||
|
|
||||||
UsePrivateHeaders libroot net ;
|
UsePrivateHeaders libroot net ;
|
||||||
UsePrivateHeaders [ FDirName kernel ] ;
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
@@ -37,7 +40,6 @@ KernelStaticLibrary libkernelppp.a :
|
|||||||
KPPPReportManager.cpp
|
KPPPReportManager.cpp
|
||||||
KPPPStateMachine.cpp
|
KPPPStateMachine.cpp
|
||||||
KPPPUtils.cpp
|
KPPPUtils.cpp
|
||||||
Locker.cpp
|
|
||||||
settings_tools.cpp
|
settings_tools.cpp
|
||||||
|
|
||||||
# integrated modules
|
# integrated modules
|
||||||
@@ -49,7 +51,5 @@ KernelStaticLibrary libkernelppp.a :
|
|||||||
|
|
||||||
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||||
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||||
SEARCH on [ FGristFiles Locker.cpp ]
|
|
||||||
= [ FDirName $(HAIKU_TOP) src system kernel disk_device_manager ] ;
|
|
||||||
SEARCH on [ FGristFiles atomic.S ]
|
SEARCH on [ FGristFiles atomic.S ]
|
||||||
= [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
|
= [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
|
||||||
|
|||||||
@@ -5,18 +5,20 @@
|
|||||||
|
|
||||||
/*! \class KPPPConfigurePacket
|
/*! \class KPPPConfigurePacket
|
||||||
\brief Helper class for LCP configure packets.
|
\brief Helper class for LCP configure packets.
|
||||||
|
|
||||||
This class allows iterating over configure items and adding/removing items.
|
This class allows iterating over configure items and adding/removing items.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
#include <KPPPConfigurePacket.h>
|
#include <KPPPConfigurePacket.h>
|
||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
|
|
||||||
#include <core_funcs.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Constructor.
|
/*! \brief Constructor.
|
||||||
|
|
||||||
\param code The code value (e.g.: PPP_CONFIGURE_REQUEST) of this packet.
|
\param code The code value (e.g.: PPP_CONFIGURE_REQUEST) of this packet.
|
||||||
*/
|
*/
|
||||||
KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
|
KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
|
||||||
@@ -27,30 +29,33 @@ KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
|
|||||||
|
|
||||||
|
|
||||||
//! Decodes a packet and adds its items to this object.
|
//! Decodes a packet and adds its items to this object.
|
||||||
KPPPConfigurePacket::KPPPConfigurePacket(struct mbuf *packet)
|
KPPPConfigurePacket::KPPPConfigurePacket(net_buffer *packet)
|
||||||
{
|
{
|
||||||
// decode packet
|
// decode packet
|
||||||
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferhead(packet);
|
||||||
|
if (bufferhead.Status() != B_OK)
|
||||||
SetID(header->id);
|
|
||||||
if (!SetCode(header->code))
|
|
||||||
return;
|
return;
|
||||||
|
ppp_lcp_packet &header = bufferhead.Data();
|
||||||
uint16 length = ntohs(header->length);
|
|
||||||
|
SetID(header.id);
|
||||||
if (length < 6 || length > packet->m_len)
|
if (!SetCode(header.code))
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint16 length = ntohs(header.length);
|
||||||
|
|
||||||
|
if (length < 6 || length > packet->size)
|
||||||
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 < length - 4) {
|
while (position < length - 4) {
|
||||||
item = (ppp_configure_item*) (header->data + position);
|
item = (ppp_configure_item*) (header.data + position);
|
||||||
if (item->length < 2)
|
if (item->length < 2)
|
||||||
return;
|
return;
|
||||||
// found a corrupted item
|
// found a corrupted item
|
||||||
|
|
||||||
position += item->length;
|
position += item->length;
|
||||||
AddItem(item);
|
AddItem(item);
|
||||||
}
|
}
|
||||||
@@ -72,23 +77,23 @@ KPPPConfigurePacket::SetCode(uint8 code)
|
|||||||
// only configure codes are allowed!
|
// only configure codes are allowed!
|
||||||
if (code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT)
|
if (code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fCode = code;
|
fCode = code;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Adds a new configure item to this packet.
|
/*! \brief Adds a new configure item to this packet.
|
||||||
|
|
||||||
Make sure all values are correct because the item will be copied. If the item's
|
Make sure all values are correct because the item will be copied. If the item's
|
||||||
length field is incorrect you will get bad results.
|
length field is incorrect you will get bad results.
|
||||||
|
|
||||||
\param item The item.
|
\param item The item.
|
||||||
\param index Item's index. Adds after the last item if not specified or negative.
|
\param index Item's index. Adds after the last item if not specified or negative.
|
||||||
|
|
||||||
\return \c true if successful, \c false otherwise.
|
\return \c true if successful, \c false otherwise.
|
||||||
|
|
||||||
\sa ppp_configure_item
|
\sa ppp_configure_item
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
@@ -96,10 +101,10 @@ KPPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index)
|
|||||||
{
|
{
|
||||||
if (!item || 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);
|
||||||
memcpy(add, item, item->length);
|
memcpy(add, item, item->length);
|
||||||
|
|
||||||
bool status;
|
bool status;
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
status = fItems.AddItem(add);
|
status = fItems.AddItem(add);
|
||||||
@@ -109,7 +114,7 @@ KPPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index)
|
|||||||
free(add);
|
free(add);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,10 +125,10 @@ KPPPConfigurePacket::RemoveItem(ppp_configure_item *item)
|
|||||||
{
|
{
|
||||||
if (!fItems.HasItem(item))
|
if (!fItems.HasItem(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fItems.RemoveItem(item);
|
fItems.RemoveItem(item);
|
||||||
free(item);
|
free(item);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,10 +138,10 @@ ppp_configure_item*
|
|||||||
KPPPConfigurePacket::ItemAt(int32 index) const
|
KPPPConfigurePacket::ItemAt(int32 index) const
|
||||||
{
|
{
|
||||||
ppp_configure_item *item = fItems.ItemAt(index);
|
ppp_configure_item *item = fItems.ItemAt(index);
|
||||||
|
|
||||||
if (item == fItems.GetDefaultItem())
|
if (item == fItems.GetDefaultItem())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,56 +151,71 @@ ppp_configure_item*
|
|||||||
KPPPConfigurePacket::ItemWithType(uint8 type) const
|
KPPPConfigurePacket::ItemWithType(uint8 type) const
|
||||||
{
|
{
|
||||||
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);
|
||||||
if (item && item->type == type)
|
if (item && item->type == type)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Converts this packet into an mbuf structure.
|
/*! \brief Converts this packet into an net_buffer structure.
|
||||||
|
|
||||||
ATTENTION: You are responsible for freeing this packet by calling \c m_freem()!
|
ATTENTION: You are responsible for freeing this packet by calling \c m_freem()!
|
||||||
|
|
||||||
\param MRU The interface's maximum receive unit (MRU).
|
\param MRU The interface's maximum receive unit (MRU).
|
||||||
\param reserve Number of bytes to reserve at the beginning of the packet.
|
\param reserve Number of bytes to reserve at the beginning of the packet.
|
||||||
|
|
||||||
\return The mbuf structure or \c NULL on error (e.g.: too big for given MRU).
|
\return The net_buffer structure or \c NULL on error (e.g.: too big for given MRU).
|
||||||
*/
|
*/
|
||||||
struct mbuf*
|
net_buffer*
|
||||||
KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve)
|
KPPPConfigurePacket::ToNetBuffer(uint32 MRU)
|
||||||
{
|
{
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
net_buffer *buffer = gBufferModule->create(256);
|
||||||
packet->m_data += reserve;
|
if (buffer == NULL) {
|
||||||
|
TRACE("%s::%s: gBufferModule->create fail\n", __FILE__, __func__);
|
||||||
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_lcp_packet *header;
|
||||||
|
status_t status = gBufferModule->append_size(buffer, 1492, (void **)&header);
|
||||||
|
if (status != B_OK) {
|
||||||
|
TRACE("%s::%s: gBufferModule->append_size\n", __FILE__, __func__);
|
||||||
|
gBufferModule->free(buffer);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
header->code = Code();
|
header->code = Code();
|
||||||
header->id = ID();
|
header->id = ID();
|
||||||
|
|
||||||
uint16 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 (MRU - length < item->length) {
|
if (MRU - length < item->length) {
|
||||||
m_freem(packet);
|
gBufferModule->free(buffer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(header->data + length, item, item->length);
|
memcpy(header->data + length, item, item->length);
|
||||||
length += item->length;
|
length += item->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
length += 4;
|
length += 4;
|
||||||
header->length = htons(length);
|
header->length = htons(length);
|
||||||
packet->m_pkthdr.len = packet->m_len = length;
|
|
||||||
|
status = gBufferModule->trim(buffer, length);
|
||||||
return packet;
|
if (status < B_OK) {
|
||||||
|
dprintf("%s::%s: gBufferModule->trim\n", __FILE__, __func__);
|
||||||
|
gBufferModule->free(buffer);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
/*! \class KPPPDevice
|
/*! \class KPPPDevice
|
||||||
\brief Represents a device at the lowest level of the communcation stack.
|
\brief Represents a device at the lowest level of the communcation stack.
|
||||||
|
|
||||||
A device may be, for example: Modem, PPPoE, PPTP. \n
|
A device may be, for example: Modem, PPPoE, PPTP. \n
|
||||||
It encapsulates the packet and sends it over a line to the other end.
|
It encapsulates the packet and sends it over a line to the other end.
|
||||||
The device is the first layer that receives a packet.
|
The device is the first layer that receives a packet.
|
||||||
@@ -14,13 +14,12 @@
|
|||||||
#include <KPPPDevice.h>
|
#include <KPPPDevice.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
|
|
||||||
#include <PPPControl.h>
|
#include <PPPControl.h>
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Initializes the device.
|
/*! \brief Initializes the device.
|
||||||
|
|
||||||
\param name The device's type name (e.g.: PPPoE).
|
\param name The device's type name (e.g.: PPPoE).
|
||||||
\param overhead Length of the header that is prepended to each packet.
|
\param overhead Length of the header that is prepended to each packet.
|
||||||
\param interface Owning interface.
|
\param interface Owning interface.
|
||||||
@@ -46,12 +45,13 @@ KPPPDevice::~KPPPDevice()
|
|||||||
|
|
||||||
|
|
||||||
/*! \brief Allows private extensions.
|
/*! \brief Allows private extensions.
|
||||||
|
|
||||||
If you override this method you must call the parent's method for unknown ops.
|
If you override this method you must call the parent's method for unknown ops.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
KPPPDevice::Control(uint32 op, void *data, size_t length)
|
KPPPDevice::Control(uint32 op, void *data, size_t length)
|
||||||
{
|
{
|
||||||
|
dprintf("KPPPDevice::Control\n");
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case PPPC_GET_DEVICE_INFO:
|
case PPPC_GET_DEVICE_INFO:
|
||||||
{
|
{
|
||||||
@@ -89,7 +89,7 @@ KPPPDevice::IsAllowedToSend() const
|
|||||||
|
|
||||||
//! This method is never used.
|
//! This method is never used.
|
||||||
status_t
|
status_t
|
||||||
KPPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
KPPPDevice::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
// let the interface handle the packet
|
// let the interface handle the packet
|
||||||
if (protocolNumber == 0)
|
if (protocolNumber == 0)
|
||||||
@@ -100,10 +100,10 @@ KPPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
|
|
||||||
|
|
||||||
/*! \brief Report that device is going up.
|
/*! \brief Report that device is going up.
|
||||||
|
|
||||||
Called by Up(). \n
|
Called by Up(). \n
|
||||||
From now on, the connection attempt can may be aborted by calling Down().
|
From now on, the connection attempt can may be aborted by calling Down().
|
||||||
|
|
||||||
\return
|
\return
|
||||||
- \c true: You are allowed to connect.
|
- \c true: You are allowed to connect.
|
||||||
- \c false: You should abort immediately. Down() will \e not be called!
|
- \c false: You should abort immediately. Down() will \e not be called!
|
||||||
@@ -112,15 +112,15 @@ bool
|
|||||||
KPPPDevice::UpStarted()
|
KPPPDevice::UpStarted()
|
||||||
{
|
{
|
||||||
fConnectionPhase = PPP_ESTABLISHMENT_PHASE;
|
fConnectionPhase = PPP_ESTABLISHMENT_PHASE;
|
||||||
|
|
||||||
return Interface().StateMachine().TLSNotify();
|
return Interface().StateMachine().TLSNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Report that device is going down.
|
/*! \brief Report that device is going down.
|
||||||
|
|
||||||
Called by Down().
|
Called by Down().
|
||||||
|
|
||||||
\return
|
\return
|
||||||
- \c true: You are allowed to disconnect.
|
- \c true: You are allowed to disconnect.
|
||||||
- \c false: You must not disconnect!
|
- \c false: You must not disconnect!
|
||||||
@@ -129,7 +129,7 @@ bool
|
|||||||
KPPPDevice::DownStarted()
|
KPPPDevice::DownStarted()
|
||||||
{
|
{
|
||||||
fConnectionPhase = PPP_TERMINATION_PHASE;
|
fConnectionPhase = PPP_TERMINATION_PHASE;
|
||||||
|
|
||||||
return Interface().StateMachine().TLFNotify();
|
return Interface().StateMachine().TLFNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ void
|
|||||||
KPPPDevice::UpFailedEvent()
|
KPPPDevice::UpFailedEvent()
|
||||||
{
|
{
|
||||||
fConnectionPhase = PPP_DOWN_PHASE;
|
fConnectionPhase = PPP_DOWN_PHASE;
|
||||||
|
|
||||||
Interface().StateMachine().UpFailedEvent();
|
Interface().StateMachine().UpFailedEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ void
|
|||||||
KPPPDevice::UpEvent()
|
KPPPDevice::UpEvent()
|
||||||
{
|
{
|
||||||
fConnectionPhase = PPP_ESTABLISHED_PHASE;
|
fConnectionPhase = PPP_ESTABLISHED_PHASE;
|
||||||
|
|
||||||
Interface().StateMachine().UpEvent();
|
Interface().StateMachine().UpEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,6 +159,6 @@ void
|
|||||||
KPPPDevice::DownEvent()
|
KPPPDevice::DownEvent()
|
||||||
{
|
{
|
||||||
fConnectionPhase = PPP_DOWN_PHASE;
|
fConnectionPhase = PPP_DOWN_PHASE;
|
||||||
|
|
||||||
Interface().StateMachine().DownEvent();
|
Interface().StateMachine().DownEvent();
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
/*! \class KPPPLCP
|
/*! \class KPPPLCP
|
||||||
\brief The LCP protocol.
|
\brief The LCP protocol.
|
||||||
|
|
||||||
Every PPP interface \e must have an LCP protocol. It is used for establishing
|
Every PPP interface \e must have an LCP protocol. It is used for establishing
|
||||||
and terminating connections. \n
|
and terminating connections. \n
|
||||||
When establishing a connecition the LCP protocol determines connection-specific
|
When establishing a connecition the LCP protocol determines connection-specific
|
||||||
@@ -20,9 +20,12 @@
|
|||||||
#include <KPPPOptionHandler.h>
|
#include <KPPPOptionHandler.h>
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
|
#include <net_buffer.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
extern net_buffer_module_info *gBufferModule;
|
||||||
|
|
||||||
|
|
||||||
//! Creates a new LCP protocol for the given interface.
|
//! Creates a new LCP protocol for the given interface.
|
||||||
KPPPLCP::KPPPLCP(KPPPInterface& interface)
|
KPPPLCP::KPPPLCP(KPPPInterface& interface)
|
||||||
@@ -48,7 +51,7 @@ KPPPLCP::~KPPPLCP()
|
|||||||
|
|
||||||
|
|
||||||
/*! \brief Adds a new option handler.
|
/*! \brief Adds a new option handler.
|
||||||
|
|
||||||
NOTE: You can only add option handlers in \c PPP_DOWN_PHASE. \n
|
NOTE: You can only add option handlers in \c PPP_DOWN_PHASE. \n
|
||||||
There may only be one handler per option type!
|
There may only be one handler per option type!
|
||||||
*/
|
*/
|
||||||
@@ -57,19 +60,19 @@ KPPPLCP::AddOptionHandler(KPPPOptionHandler *optionHandler)
|
|||||||
{
|
{
|
||||||
if (!optionHandler || &optionHandler->Interface() != &Interface())
|
if (!optionHandler || &optionHandler->Interface() != &Interface())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Interface().Phase() != PPP_DOWN_PHASE
|
if (Interface().Phase() != PPP_DOWN_PHASE
|
||||||
|| OptionHandlerFor(optionHandler->Type()))
|
|| OptionHandlerFor(optionHandler->Type()))
|
||||||
return false;
|
return false;
|
||||||
// a running connection may not change and there may only be
|
// a running connection may not change and there may only be
|
||||||
// one handler per option type
|
// one handler per option type
|
||||||
|
|
||||||
return fOptionHandlers.AddItem(optionHandler);
|
return fOptionHandlers.AddItem(optionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Removes an option handler, but does not delete it.
|
/*! \brief Removes an option handler, but does not delete it.
|
||||||
|
|
||||||
NOTE: You can only remove option handlers in \c PPP_DOWN_PHASE.
|
NOTE: You can only remove option handlers in \c PPP_DOWN_PHASE.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
@@ -78,7 +81,7 @@ KPPPLCP::RemoveOptionHandler(KPPPOptionHandler *optionHandler)
|
|||||||
if (Interface().Phase() != PPP_DOWN_PHASE)
|
if (Interface().Phase() != PPP_DOWN_PHASE)
|
||||||
return false;
|
return false;
|
||||||
// a running connection may not change
|
// a running connection may not change
|
||||||
|
|
||||||
return fOptionHandlers.RemoveItem(optionHandler);
|
return fOptionHandlers.RemoveItem(optionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,11 +90,12 @@ KPPPLCP::RemoveOptionHandler(KPPPOptionHandler *optionHandler)
|
|||||||
KPPPOptionHandler*
|
KPPPOptionHandler*
|
||||||
KPPPLCP::OptionHandlerAt(int32 index) const
|
KPPPLCP::OptionHandlerAt(int32 index) const
|
||||||
{
|
{
|
||||||
|
dprintf("total optionhandler count %ld\n", CountOptionHandlers());
|
||||||
KPPPOptionHandler *optionHandler = fOptionHandlers.ItemAt(index);
|
KPPPOptionHandler *optionHandler = fOptionHandlers.ItemAt(index);
|
||||||
|
|
||||||
if (optionHandler == fOptionHandlers.GetDefaultItem())
|
if (optionHandler == fOptionHandlers.GetDefaultItem())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return optionHandler;
|
return optionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,14 +107,14 @@ KPPPLCP::OptionHandlerFor(uint8 type, int32 *start) const
|
|||||||
// The iteration style in this method is strange C/C++.
|
// The iteration style in this method is strange C/C++.
|
||||||
// Explanation: I use this style because it makes extending all XXXFor
|
// Explanation: I use this style because it makes extending all XXXFor
|
||||||
// methods simpler as that they look very similar, now.
|
// methods simpler as that they look very similar, now.
|
||||||
|
|
||||||
int32 index = start ? *start : 0;
|
int32 index = start ? *start : 0;
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
KPPPOptionHandler *current = OptionHandlerAt(index);
|
KPPPOptionHandler *current = OptionHandlerAt(index);
|
||||||
|
|
||||||
for (; current; current = OptionHandlerAt(++index)) {
|
for (; current; current = OptionHandlerAt(++index)) {
|
||||||
if (current->Type() == type) {
|
if (current->Type() == type) {
|
||||||
if (start)
|
if (start)
|
||||||
@@ -118,13 +122,13 @@ KPPPLCP::OptionHandlerFor(uint8 type, int32 *start) const
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Adds a new LCP extension.
|
/*! \brief Adds a new LCP extension.
|
||||||
|
|
||||||
NOTE: You can only add LCP extensions in \c PPP_DOWN_PHASE.
|
NOTE: You can only add LCP extensions in \c PPP_DOWN_PHASE.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
@@ -132,17 +136,17 @@ KPPPLCP::AddLCPExtension(KPPPLCPExtension *lcpExtension)
|
|||||||
{
|
{
|
||||||
if (!lcpExtension || &lcpExtension->Interface() != &Interface())
|
if (!lcpExtension || &lcpExtension->Interface() != &Interface())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Interface().Phase() != PPP_DOWN_PHASE)
|
if (Interface().Phase() != PPP_DOWN_PHASE)
|
||||||
return false;
|
return false;
|
||||||
// a running connection may not change
|
// a running connection may not change
|
||||||
|
|
||||||
return fLCPExtensions.AddItem(lcpExtension);
|
return fLCPExtensions.AddItem(lcpExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Removes an LCP extension, but does not delete it.
|
/*! \brief Removes an LCP extension, but does not delete it.
|
||||||
|
|
||||||
NOTE: You can only remove LCP extensions in \c PPP_DOWN_PHASE.
|
NOTE: You can only remove LCP extensions in \c PPP_DOWN_PHASE.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
@@ -151,7 +155,7 @@ KPPPLCP::RemoveLCPExtension(KPPPLCPExtension *lcpExtension)
|
|||||||
if (Interface().Phase() != PPP_DOWN_PHASE)
|
if (Interface().Phase() != PPP_DOWN_PHASE)
|
||||||
return false;
|
return false;
|
||||||
// a running connection may not change
|
// a running connection may not change
|
||||||
|
|
||||||
return fLCPExtensions.RemoveItem(lcpExtension);
|
return fLCPExtensions.RemoveItem(lcpExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,11 +164,12 @@ KPPPLCP::RemoveLCPExtension(KPPPLCPExtension *lcpExtension)
|
|||||||
KPPPLCPExtension*
|
KPPPLCPExtension*
|
||||||
KPPPLCP::LCPExtensionAt(int32 index) const
|
KPPPLCP::LCPExtensionAt(int32 index) const
|
||||||
{
|
{
|
||||||
|
dprintf("LCPExtension count %ld\n", CountLCPExtensions());
|
||||||
KPPPLCPExtension *lcpExtension = fLCPExtensions.ItemAt(index);
|
KPPPLCPExtension *lcpExtension = fLCPExtensions.ItemAt(index);
|
||||||
|
|
||||||
if (lcpExtension == fLCPExtensions.GetDefaultItem())
|
if (lcpExtension == fLCPExtensions.GetDefaultItem())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return lcpExtension;
|
return lcpExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,14 +181,14 @@ KPPPLCP::LCPExtensionFor(uint8 code, int32 *start) const
|
|||||||
// The iteration style in this method is strange C/C++.
|
// The iteration style in this method is strange C/C++.
|
||||||
// Explanation: I use this style because it makes extending all XXXFor
|
// Explanation: I use this style because it makes extending all XXXFor
|
||||||
// methods simpler as that they look very similar, now.
|
// methods simpler as that they look very similar, now.
|
||||||
|
|
||||||
int32 index = start ? *start : 0;
|
int32 index = start ? *start : 0;
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
KPPPLCPExtension *current = LCPExtensionAt(index);
|
KPPPLCPExtension *current = LCPExtensionAt(index);
|
||||||
|
|
||||||
for (; current; current = LCPExtensionAt(++index)) {
|
for (; current; current = LCPExtensionAt(++index)) {
|
||||||
if (current->Code() == code) {
|
if (current->Code() == code) {
|
||||||
if (start)
|
if (start)
|
||||||
@@ -191,27 +196,11 @@ KPPPLCP::LCPExtensionFor(uint8 code, int32 *start) const
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Returns the interface, target, and device overhead.
|
|
||||||
uint32
|
|
||||||
KPPPLCP::AdditionalOverhead() const
|
|
||||||
{
|
|
||||||
uint32 overhead = Interface().Overhead();
|
|
||||||
|
|
||||||
if (Target())
|
|
||||||
overhead += Target()->Overhead();
|
|
||||||
|
|
||||||
if (Interface().Device())
|
|
||||||
overhead += Interface().Device()->Overhead();
|
|
||||||
|
|
||||||
return overhead;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Always returns \c true.
|
//! Always returns \c true.
|
||||||
bool
|
bool
|
||||||
KPPPLCP::Up()
|
KPPPLCP::Up()
|
||||||
@@ -230,7 +219,7 @@ KPPPLCP::Down()
|
|||||||
|
|
||||||
//! Sends a packet to the target (if there is one) or to the interface.
|
//! Sends a packet to the target (if there is one) or to the interface.
|
||||||
status_t
|
status_t
|
||||||
KPPPLCP::Send(struct mbuf *packet, uint16 protocolNumber)
|
KPPPLCP::Send(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
if (Target())
|
if (Target())
|
||||||
return Target()->Send(packet, PPP_LCP_PROTOCOL);
|
return Target()->Send(packet, PPP_LCP_PROTOCOL);
|
||||||
@@ -241,39 +230,32 @@ KPPPLCP::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
|
|
||||||
//! Decodes the LCP packet and passes it to the KPPPStateMachine or an LCP extension.
|
//! Decodes the LCP packet and passes it to the KPPPStateMachine or an LCP extension.
|
||||||
status_t
|
status_t
|
||||||
KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
KPPPLCP::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if (protocolNumber != PPP_LCP_PROTOCOL) {
|
if (protocolNumber != PPP_LCP_PROTOCOL) {
|
||||||
ERROR("KPPPLCP::Receive(): wrong protocol number!\n");
|
ERROR("KPPPLCP::Receive(): wrong protocol number!\n");
|
||||||
return PPP_UNHANDLED;
|
return PPP_UNHANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return bufferHeader.Status();
|
||||||
|
|
||||||
|
ppp_lcp_packet &data = bufferHeader.Data();
|
||||||
|
|
||||||
// remove padding
|
// remove padding
|
||||||
int32 length = packet->m_len;
|
|
||||||
if (packet->m_flags & M_PKTHDR)
|
net_buffer *copy = gBufferModule->duplicate(packet);
|
||||||
length = packet->m_pkthdr.len;
|
|
||||||
length -= ntohs(data->length);
|
if (ntohs(data.length) < 4)
|
||||||
if (length)
|
|
||||||
m_adj(packet, -length);
|
|
||||||
|
|
||||||
struct mbuf *copy = m_gethdr(MT_DATA);
|
|
||||||
if (copy) {
|
|
||||||
copy->m_data += AdditionalOverhead();
|
|
||||||
copy->m_pkthdr.len = copy->m_len = packet->m_len;
|
|
||||||
memcpy(copy->m_data, packet->m_data, copy->m_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ntohs(data->length) < 4)
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
|
|
||||||
switch (data->code) {
|
switch (data.code) {
|
||||||
case PPP_CONFIGURE_REQUEST:
|
case PPP_CONFIGURE_REQUEST:
|
||||||
StateMachine().RCREvent(packet);
|
StateMachine().RCREvent(packet);
|
||||||
break;
|
break;
|
||||||
@@ -310,43 +292,43 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
handled = false;
|
handled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = copy;
|
packet = copy;
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return handled ? B_OK : B_ERROR;
|
return handled ? B_OK : B_ERROR;
|
||||||
|
|
||||||
status_t result = B_OK;
|
status_t result = B_OK;
|
||||||
|
|
||||||
// Try to find LCP extensions that can handle this code.
|
// Try to find LCP extensions that can handle this code.
|
||||||
// We must duplicate the packet in order to ask all handlers.
|
// We must duplicate the packet in order to ask all handlers.
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
KPPPLCPExtension *lcpExtension = LCPExtensionFor(data->code, &index);
|
KPPPLCPExtension *lcpExtension = LCPExtensionFor(data.code, &index);
|
||||||
for (; lcpExtension; lcpExtension = LCPExtensionFor(data->code, &(++index))) {
|
for (; lcpExtension; lcpExtension = LCPExtensionFor(data.code, &(++index))) {
|
||||||
if (!lcpExtension->IsEnabled())
|
if (!lcpExtension->IsEnabled())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result = lcpExtension->Receive(packet, data->code);
|
result = lcpExtension->Receive(packet, data.code);
|
||||||
|
|
||||||
// check return value and return it on error
|
// check return value and return it on error
|
||||||
if (result == B_OK)
|
if (result == B_OK)
|
||||||
handled = true;
|
handled = true;
|
||||||
else if (result != PPP_UNHANDLED) {
|
else if (result != PPP_UNHANDLED) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
|
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
|
||||||
return PPP_REJECTED;
|
return PPP_REJECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +338,7 @@ void
|
|||||||
KPPPLCP::Pulse()
|
KPPPLCP::Pulse()
|
||||||
{
|
{
|
||||||
StateMachine().TimerEvent();
|
StateMachine().TimerEvent();
|
||||||
|
|
||||||
for (int32 index = 0; index < CountLCPExtensions(); index++)
|
for (int32 index = 0; index < CountLCPExtensions(); index++)
|
||||||
LCPExtensionAt(index)->Pulse();
|
LCPExtensionAt(index)->Pulse();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ KPPPLCPExtension::InitCheck() const
|
|||||||
status_t
|
status_t
|
||||||
KPPPLCPExtension::Control(uint32 op, void *data, size_t length)
|
KPPPLCPExtension::Control(uint32 op, void *data, size_t length)
|
||||||
{
|
{
|
||||||
|
dprintf("KPPPLCPExtension::Control\n");
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
/*! \class KPPPLayer
|
/*! \class KPPPLayer
|
||||||
\brief An abstract layer that can encapsulate/send and receive packets.
|
\brief An abstract layer that can encapsulate/send and receive packets.
|
||||||
|
|
||||||
All packet handlers should derive from this class. It does not define a protocol
|
All packet handlers should derive from this class. It does not define a protocol
|
||||||
number like KPPPProtocol does. It only has a header overhead and an encapsulation
|
number like KPPPProtocol does. It only has a header overhead and an encapsulation
|
||||||
level that is used to determine the order at which the packets get encapsulated
|
level that is used to determine the order at which the packets get encapsulated
|
||||||
@@ -19,13 +19,15 @@
|
|||||||
|
|
||||||
#include <KPPPLayer.h>
|
#include <KPPPLayer.h>
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <core_funcs.h>
|
|
||||||
|
|
||||||
|
extern net_buffer_module_info *gBufferModule;
|
||||||
|
|
||||||
/*! \brief Creates a new layer.
|
/*! \brief Creates a new layer.
|
||||||
|
|
||||||
If an error occurs in the constructor you should set \c fInitStatus.
|
If an error occurs in the constructor you should set \c fInitStatus.
|
||||||
*/
|
*/
|
||||||
KPPPLayer::KPPPLayer(const char *name, ppp_level level, uint32 overhead)
|
KPPPLayer::KPPPLayer(const char *name, ppp_level level, uint32 overhead)
|
||||||
@@ -56,11 +58,11 @@ KPPPLayer::InitCheck() const
|
|||||||
|
|
||||||
//! Sends a packet to the next layer in the chain.
|
//! Sends a packet to the next layer in the chain.
|
||||||
status_t
|
status_t
|
||||||
KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
|
KPPPLayer::SendToNext(net_buffer *packet, uint16 protocolNumber) const
|
||||||
{
|
{
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// Find the next possible handler for this packet.
|
// Find the next possible handler for this packet.
|
||||||
// Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything.
|
// Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything.
|
||||||
if (Next()) {
|
if (Next()) {
|
||||||
@@ -70,14 +72,14 @@ KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
|
|||||||
return Next()->SendToNext(packet, protocolNumber);
|
return Next()->SendToNext(packet, protocolNumber);
|
||||||
} else {
|
} else {
|
||||||
ERROR("KPPPLayer: SendToNext() failed because there is no next handler!\n");
|
ERROR("KPPPLayer: SendToNext() failed because there is no next handler!\n");
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief You may override this for periodic tasks.
|
/*! \brief You may override this for periodic tasks.
|
||||||
|
|
||||||
This method gets called every \c PPP_PULSE_RATE microseconds.
|
This method gets called every \c PPP_PULSE_RATE microseconds.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@@ -92,7 +94,7 @@ void
|
|||||||
KPPPLayer::SetName(const char *name)
|
KPPPLayer::SetName(const char *name)
|
||||||
{
|
{
|
||||||
free(fName);
|
free(fName);
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
fName = strdup(name);
|
fName = strdup(name);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ KPPPOptionHandler::InitCheck() const
|
|||||||
status_t
|
status_t
|
||||||
KPPPOptionHandler::Control(uint32 op, void *data, size_t length)
|
KPPPOptionHandler::Control(uint32 op, void *data, size_t length)
|
||||||
{
|
{
|
||||||
|
dprintf("KPPPOptionHandler::Control\n");
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
#include <KPPPReportManager.h>
|
#include <KPPPReportManager.h>
|
||||||
|
|
||||||
#include <LockerHelper.h>
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
#include <KPPPUtils.h>
|
#include <KPPPUtils.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -30,10 +32,10 @@ report_sender_thread(void *data)
|
|||||||
|
|
||||||
|
|
||||||
/*! \brief Constructor.
|
/*! \brief Constructor.
|
||||||
|
|
||||||
\param lock The BLocker that should be used by this report manager.
|
\param lock The BLocker that should be used by this report manager.
|
||||||
*/
|
*/
|
||||||
KPPPReportManager::KPPPReportManager(BLocker& lock)
|
KPPPReportManager::KPPPReportManager(mutex& lock)
|
||||||
: fLock(lock)
|
: fLock(lock)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -48,10 +50,10 @@ KPPPReportManager::~KPPPReportManager()
|
|||||||
|
|
||||||
|
|
||||||
/*! \brief Send the given report message to the given thread.
|
/*! \brief Send the given report message to the given thread.
|
||||||
|
|
||||||
\param thread The report receiver.
|
\param thread The report receiver.
|
||||||
\param report The report message.
|
\param report The report message.
|
||||||
|
|
||||||
\return \c false on error.
|
\return \c false on error.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
@@ -59,7 +61,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
|
|||||||
{
|
{
|
||||||
if (!report)
|
if (!report)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (thread == find_thread(NULL)) {
|
if (thread == find_thread(NULL)) {
|
||||||
report_sender_info *info = new report_sender_info;
|
report_sender_info *info = new report_sender_info;
|
||||||
info->thread = thread;
|
info->thread = thread;
|
||||||
@@ -68,7 +70,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
|
|||||||
B_NORMAL_PRIORITY, info));
|
B_NORMAL_PRIORITY, info));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
send_data_with_timeout(thread, PPP_REPORT_CODE, &report, sizeof(report),
|
send_data_with_timeout(thread, PPP_REPORT_CODE, &report, sizeof(report),
|
||||||
PPP_REPORT_TIMEOUT);
|
PPP_REPORT_TIMEOUT);
|
||||||
return true;
|
return true;
|
||||||
@@ -76,7 +78,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
|
|||||||
|
|
||||||
|
|
||||||
/*! \brief Requests report messages of a given \a type.
|
/*! \brief Requests report messages of a given \a type.
|
||||||
|
|
||||||
\param type The type of report.
|
\param type The type of report.
|
||||||
\param thread The receiver thread.
|
\param thread The receiver thread.
|
||||||
\param flags Optional report flags. See \c ppp_report_flags for more information.
|
\param flags Optional report flags. See \c ppp_report_flags for more information.
|
||||||
@@ -87,14 +89,14 @@ KPPPReportManager::EnableReports(ppp_report_type type, thread_id thread,
|
|||||||
{
|
{
|
||||||
if (thread < 0 || type == PPP_ALL_REPORTS)
|
if (thread < 0 || type == PPP_ALL_REPORTS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
ppp_report_request *request = new ppp_report_request;
|
ppp_report_request *request = new ppp_report_request;
|
||||||
request->type = type;
|
request->type = type;
|
||||||
request->thread = thread;
|
request->thread = thread;
|
||||||
request->flags = flags;
|
request->flags = flags;
|
||||||
|
|
||||||
fReportRequests.AddItem(request);
|
fReportRequests.AddItem(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,21 +107,21 @@ KPPPReportManager::DisableReports(ppp_report_type type, thread_id thread)
|
|||||||
{
|
{
|
||||||
if (thread < 0)
|
if (thread < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
ppp_report_request *request;
|
ppp_report_request *request;
|
||||||
|
|
||||||
for (int32 i = 0; i < fReportRequests.CountItems(); i++) {
|
for (int32 i = 0; i < fReportRequests.CountItems(); i++) {
|
||||||
request = fReportRequests.ItemAt(i);
|
request = fReportRequests.ItemAt(i);
|
||||||
|
|
||||||
if (request->thread != thread)
|
if (request->thread != thread)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (request->type == type || type == PPP_ALL_REPORTS)
|
if (request->type == type || type == PPP_ALL_REPORTS)
|
||||||
fReportRequests.RemoveItem(request);
|
fReportRequests.RemoveItem(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// empty message queue
|
// empty message queue
|
||||||
while (has_data(thread)) {
|
while (has_data(thread)) {
|
||||||
thread_id sender;
|
thread_id sender;
|
||||||
@@ -134,32 +136,32 @@ KPPPReportManager::DoesReport(ppp_report_type type, thread_id thread)
|
|||||||
{
|
{
|
||||||
if (thread < 0)
|
if (thread < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
ppp_report_request *request;
|
ppp_report_request *request;
|
||||||
|
|
||||||
for (int32 i = 0; i < fReportRequests.CountItems(); i++) {
|
for (int32 i = 0; i < fReportRequests.CountItems(); i++) {
|
||||||
request = fReportRequests.ItemAt(i);
|
request = fReportRequests.ItemAt(i);
|
||||||
|
|
||||||
if (request->thread == thread && request->type == type)
|
if (request->thread == thread && request->type == type)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Send out report messages to all requestors.
|
/*! \brief Send out report messages to all requestors.
|
||||||
|
|
||||||
You may append additional data to the report messages. The data length may not be
|
You may append additional data to the report messages. The data length may not be
|
||||||
greater than \c PPP_REPORT_DATA_LIMIT.
|
greater than \c PPP_REPORT_DATA_LIMIT.
|
||||||
|
|
||||||
\param type The report type.
|
\param type The report type.
|
||||||
\param code The report code belonging to the report type.
|
\param code The report code belonging to the report type.
|
||||||
\param data Additional data.
|
\param data Additional data.
|
||||||
\param length Length of the data.
|
\param length Length of the data.
|
||||||
|
|
||||||
\return \c false on error.
|
\return \c false on error.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
@@ -167,44 +169,44 @@ KPPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 le
|
|||||||
{
|
{
|
||||||
TRACE("KPPPReportManager: Report(type=%d code=%ld length=%ld) to %ld receivers\n",
|
TRACE("KPPPReportManager: Report(type=%d code=%ld length=%ld) to %ld receivers\n",
|
||||||
type, code, length, fReportRequests.CountItems());
|
type, code, length, fReportRequests.CountItems());
|
||||||
|
|
||||||
if (length > PPP_REPORT_DATA_LIMIT)
|
if (length > PPP_REPORT_DATA_LIMIT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fReportRequests.CountItems() == 0)
|
if (fReportRequests.CountItems() == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
length = 0;
|
length = 0;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
status_t result;
|
status_t result;
|
||||||
thread_id me = find_thread(NULL);
|
thread_id me = find_thread(NULL);
|
||||||
|
|
||||||
ppp_report_packet report;
|
ppp_report_packet report;
|
||||||
report.type = type;
|
report.type = type;
|
||||||
report.code = code;
|
report.code = code;
|
||||||
report.length = length;
|
report.length = length;
|
||||||
memcpy(report.data, data, length);
|
memcpy(report.data, data, length);
|
||||||
|
|
||||||
ppp_report_request *request;
|
ppp_report_request *request;
|
||||||
|
|
||||||
for (int32 index = 0; index < fReportRequests.CountItems(); index++) {
|
for (int32 index = 0; index < fReportRequests.CountItems(); index++) {
|
||||||
request = fReportRequests.ItemAt(index);
|
request = fReportRequests.ItemAt(index);
|
||||||
|
|
||||||
// do not send to yourself
|
// do not send to yourself
|
||||||
if (request->thread == me)
|
if (request->thread == me)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
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 DEBUG
|
||||||
if (result == B_TIMED_OUT)
|
if (result == B_TIMED_OUT)
|
||||||
TRACE("KPPPReportManager::Report(): timed out sending\n");
|
TRACE("KPPPReportManager::Report(): timed out sending\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (result == B_BAD_THREAD_ID || result == B_NO_MEMORY
|
if (result == B_BAD_THREAD_ID || result == B_NO_MEMORY
|
||||||
|| request->flags & PPP_REMOVE_AFTER_REPORT) {
|
|| request->flags & PPP_REMOVE_AFTER_REPORT) {
|
||||||
fReportRequests.RemoveItem(request);
|
fReportRequests.RemoveItem(request);
|
||||||
@@ -212,6 +214,6 @@ KPPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 le
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,7 @@
|
|||||||
#define _K_PPP_CONFIGURE_PACKET__H
|
#define _K_PPP_CONFIGURE_PACKET__H
|
||||||
|
|
||||||
#include <TemplateList.h>
|
#include <TemplateList.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
struct mbuf;
|
|
||||||
|
|
||||||
//! An abstract configure item.
|
//! An abstract configure item.
|
||||||
typedef struct ppp_configure_item {
|
typedef struct ppp_configure_item {
|
||||||
@@ -29,7 +28,7 @@ class KPPPConfigurePacket {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
KPPPConfigurePacket(uint8 code);
|
KPPPConfigurePacket(uint8 code);
|
||||||
KPPPConfigurePacket(struct mbuf *packet);
|
KPPPConfigurePacket(net_buffer *packet);
|
||||||
~KPPPConfigurePacket();
|
~KPPPConfigurePacket();
|
||||||
|
|
||||||
bool SetCode(uint8 code);
|
bool SetCode(uint8 code);
|
||||||
@@ -52,8 +51,8 @@ class KPPPConfigurePacket {
|
|||||||
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 MRU, uint32 reserve = 0);
|
net_buffer *ToNetBuffer(uint32 MRU);
|
||||||
// the user is responsible for freeing the mbuf
|
// the user is responsible for freeing the net_buffer
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 fCode, fID;
|
uint8 fCode, fID;
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <KPPPDefs.h>
|
#include <KPPPDefs.h>
|
||||||
#include <KPPPLayer.h>
|
#include <KPPPLayer.h>
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
|
||||||
#ifndef _K_PPP_INTERFACE__H
|
#ifndef _K_PPP_INTERFACE__H
|
||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -96,8 +98,8 @@ class KPPPDevice : public KPPPLayer {
|
|||||||
This should enqueue the packet and return immediately (never block).
|
This should enqueue the packet and return immediately (never block).
|
||||||
The device is responsible for freeing the packet by calling \c m_freem().
|
The device is responsible for freeing the packet by calling \c m_freem().
|
||||||
*/
|
*/
|
||||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
|
virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Use this to set the device's maximum transfer unit (in bytes).
|
//! Use this to set the device's maximum transfer unit (in bytes).
|
||||||
|
|||||||
@@ -30,6 +30,12 @@
|
|||||||
|
|
||||||
#include <TemplateList.h>
|
#include <TemplateList.h>
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_device.h>
|
||||||
|
|
||||||
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
class KPPPDevice;
|
class KPPPDevice;
|
||||||
class KPPPProtocol;
|
class KPPPProtocol;
|
||||||
class KPPPOptionHandler;
|
class KPPPOptionHandler;
|
||||||
@@ -48,6 +54,8 @@ class KPPPInterface : public KPPPLayer {
|
|||||||
KPPPInterface(const KPPPInterface& copy);
|
KPPPInterface(const KPPPInterface& copy);
|
||||||
KPPPInterface& operator= (const KPPPInterface& copy);
|
KPPPInterface& operator= (const KPPPInterface& copy);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// we should set to private after finishing test
|
||||||
// only PPPManager may construct us!
|
// only PPPManager may construct us!
|
||||||
KPPPInterface(const char *name, ppp_interface_entry *entry,
|
KPPPInterface(const char *name, ppp_interface_entry *entry,
|
||||||
ppp_interface_id ID, const driver_settings *settings,
|
ppp_interface_id ID, const driver_settings *settings,
|
||||||
@@ -75,8 +83,8 @@ class KPPPInterface : public KPPPLayer {
|
|||||||
{ return fLCP; }
|
{ return fLCP; }
|
||||||
|
|
||||||
//! Returns the interfac's ifnet structure that is exported to the netstack.
|
//! Returns the interfac's ifnet structure that is exported to the netstack.
|
||||||
struct ifnet *Ifnet() const
|
net_device *Ifnet() const
|
||||||
{ return fIfnet; }
|
{ return fIfnet; }
|
||||||
|
|
||||||
const char *Username() const;
|
const char *Username() const;
|
||||||
const char *Password() const;
|
const char *Password() const;
|
||||||
@@ -220,11 +228,11 @@ class KPPPInterface : public KPPPLayer {
|
|||||||
virtual bool IsAllowedToSend() const;
|
virtual bool IsAllowedToSend() const;
|
||||||
// always returns true
|
// always returns true
|
||||||
|
|
||||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber);
|
virtual status_t Send(net_buffer *packet, uint16 protocolNumber);
|
||||||
// sends the packet to the next handler (normally the device)
|
// sends the packet to the next handler (normally the device)
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||||
|
|
||||||
status_t ReceiveFromDevice(struct mbuf *packet);
|
status_t ReceiveFromDevice(net_buffer *packet);
|
||||||
// This must not block KPPPDevice::Send()!
|
// This must not block KPPPDevice::Send()!
|
||||||
|
|
||||||
void Pulse();
|
void Pulse();
|
||||||
@@ -255,7 +263,7 @@ class KPPPInterface : public KPPPLayer {
|
|||||||
ppp_interface_id fID;
|
ppp_interface_id fID;
|
||||||
// the manager assigns an ID to every interface
|
// the manager assigns an ID to every interface
|
||||||
driver_settings *fSettings;
|
driver_settings *fSettings;
|
||||||
struct ifnet *fIfnet;
|
net_device *fIfnet;
|
||||||
|
|
||||||
char *fUsername, *fPassword;
|
char *fUsername, *fPassword;
|
||||||
|
|
||||||
@@ -288,7 +296,7 @@ class KPPPInterface : public KPPPLayer {
|
|||||||
KPPPStateMachine fStateMachine;
|
KPPPStateMachine fStateMachine;
|
||||||
KPPPLCP fLCP;
|
KPPPLCP fLCP;
|
||||||
KPPPReportManager fReportManager;
|
KPPPReportManager fReportManager;
|
||||||
BLocker& fLock;
|
mutex& fLock;
|
||||||
int32 fDeleteCounter;
|
int32 fDeleteCounter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
#include <KPPPStateMachine.h>
|
#include <KPPPStateMachine.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
|
||||||
class KPPPLCPExtension;
|
class KPPPLCPExtension;
|
||||||
class KPPPOptionHandler;
|
class KPPPOptionHandler;
|
||||||
|
|
||||||
@@ -79,15 +82,12 @@ class KPPPLCP : public KPPPProtocol {
|
|||||||
KPPPProtocol *Target() const
|
KPPPProtocol *Target() const
|
||||||
{ return fTarget; }
|
{ return fTarget; }
|
||||||
|
|
||||||
uint32 AdditionalOverhead() const;
|
|
||||||
// the overhead caused by the target, the device, and the interface
|
|
||||||
|
|
||||||
virtual bool Up();
|
virtual bool Up();
|
||||||
virtual bool Down();
|
virtual bool Down();
|
||||||
|
|
||||||
virtual status_t Send(struct mbuf *packet,
|
virtual status_t Send(net_buffer *packet,
|
||||||
uint16 protocolNumber = PPP_LCP_PROTOCOL);
|
uint16 protocolNumber = PPP_LCP_PROTOCOL);
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||||
|
|
||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class KPPPLCPExtension {
|
|||||||
// called by netstack (forwarded by KPPPInterface)
|
// called by netstack (forwarded by KPPPInterface)
|
||||||
|
|
||||||
//! Must be overridden. Called when an LCP packet with your code is received.
|
//! Must be overridden. Called when an LCP packet with your code is received.
|
||||||
virtual status_t Receive(struct mbuf *packet, uint8 code) = 0;
|
virtual status_t Receive(net_buffer *packet, uint8 code) = 0;
|
||||||
|
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <KPPPDefs.h>
|
#include <KPPPDefs.h>
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
|
||||||
class KPPPLayer {
|
class KPPPLayer {
|
||||||
protected:
|
protected:
|
||||||
@@ -48,11 +49,11 @@ class KPPPLayer {
|
|||||||
virtual bool IsAllowedToSend() const = 0;
|
virtual bool IsAllowedToSend() const = 0;
|
||||||
|
|
||||||
//! Send a packet with the given protocol number.
|
//! Send a packet with the given protocol number.
|
||||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
|
virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||||
//! Receive a packet with the given protocol number.
|
//! Receive a packet with the given protocol number.
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0;
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||||
|
|
||||||
status_t SendToNext(struct mbuf *packet, uint16 protocolNumber) const;
|
status_t SendToNext(net_buffer *packet, uint16 protocolNumber) const;
|
||||||
// send the packet to the next layer
|
// send the packet to the next layer
|
||||||
|
|
||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
#ifndef _K_PPP_MANAGER__H
|
#ifndef _K_PPP_MANAGER__H
|
||||||
#define _K_PPP_MANAGER__H
|
#define _K_PPP_MANAGER__H
|
||||||
|
|
||||||
#include "net_module.h"
|
#include <module.h>
|
||||||
|
#include <net_device.h>
|
||||||
#include <PPPControl.h>
|
#include <PPPControl.h>
|
||||||
#include <PPPReportDefs.h>
|
#include <PPPReportDefs.h>
|
||||||
|
|
||||||
|
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/KPPPManager/v1"
|
||||||
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "interfaces/ppp"
|
|
||||||
|
|
||||||
#define PPP_UNDEFINED_INTERFACE_ID 0
|
#define PPP_UNDEFINED_INTERFACE_ID 0
|
||||||
// CreateInterface() returns this value on failure
|
// CreateInterface() returns this value on failure
|
||||||
@@ -34,8 +34,7 @@ typedef struct ppp_interface_entry {
|
|||||||
deletes them when they are not needed anymore.
|
deletes them when they are not needed anymore.
|
||||||
*/
|
*/
|
||||||
typedef struct ppp_interface_module_info {
|
typedef struct ppp_interface_module_info {
|
||||||
kernel_net_module_info knminfo;
|
struct module_info info;
|
||||||
//!< Exports needed network module functions.
|
|
||||||
|
|
||||||
ppp_interface_id (*CreateInterface)(const driver_settings *settings,
|
ppp_interface_id (*CreateInterface)(const driver_settings *settings,
|
||||||
ppp_interface_id parentID);
|
ppp_interface_id parentID);
|
||||||
@@ -46,7 +45,9 @@ typedef struct ppp_interface_module_info {
|
|||||||
bool (*RemoveInterface)(ppp_interface_id ID);
|
bool (*RemoveInterface)(ppp_interface_id ID);
|
||||||
// remove the interface from database (make sure you can delete it yourself!)
|
// remove the interface from database (make sure you can delete it yourself!)
|
||||||
|
|
||||||
ifnet *(*RegisterInterface)(ppp_interface_id ID);
|
net_device *(*RegisterInterface)(ppp_interface_id ID);
|
||||||
|
KPPPInterface *(*GetInterface)(ppp_interface_id ID);
|
||||||
|
// for accessing KPPPInterface directly
|
||||||
bool (*UnregisterInterface)(ppp_interface_id ID);
|
bool (*UnregisterInterface)(ppp_interface_id ID);
|
||||||
|
|
||||||
status_t (*ControlInterface)(ppp_interface_id ID, uint32 op, void *data,
|
status_t (*ControlInterface)(ppp_interface_id ID, uint32 op, void *data,
|
||||||
|
|||||||
@@ -105,9 +105,9 @@ class KPPPProtocol : public KPPPLayer {
|
|||||||
virtual bool IsAllowedToSend() const;
|
virtual bool IsAllowedToSend() const;
|
||||||
|
|
||||||
//! Encapsulate the packet with the given protocol number.
|
//! Encapsulate the packet with the given protocol number.
|
||||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
|
virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||||
//! Receive a packet with the given protocol number.
|
//! Receive a packet with the given protocol number.
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0;
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! \brief Requests Up() to be called.
|
//! \brief Requests Up() to be called.
|
||||||
|
|||||||
@@ -13,10 +13,13 @@
|
|||||||
|
|
||||||
#include <TemplateList.h>
|
#include <TemplateList.h>
|
||||||
|
|
||||||
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
|
|
||||||
class KPPPReportManager {
|
class KPPPReportManager {
|
||||||
public:
|
public:
|
||||||
KPPPReportManager(BLocker& lock);
|
KPPPReportManager(mutex& lock);
|
||||||
~KPPPReportManager();
|
~KPPPReportManager();
|
||||||
|
|
||||||
static bool SendReport(thread_id thread, const ppp_report_packet *report);
|
static bool SendReport(thread_id thread, const ppp_report_packet *report);
|
||||||
@@ -30,7 +33,7 @@ class KPPPReportManager {
|
|||||||
// returns false if reply was bad (or an error occured)
|
// returns false if reply was bad (or an error occured)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BLocker& fLock;
|
mutex& fLock;
|
||||||
TemplateList<ppp_report_request*> fReportRequests;
|
TemplateList<ppp_report_request*> fReportRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ class KPPPProtocol;
|
|||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Locker.h>
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
class PPPManager;
|
class PPPManager;
|
||||||
class KPPPInterface;
|
class KPPPInterface;
|
||||||
@@ -30,7 +31,7 @@ class KPPPStateMachine {
|
|||||||
// may only be constructed/destructed by KPPPInterface
|
// may only be constructed/destructed by KPPPInterface
|
||||||
KPPPStateMachine(KPPPInterface& interface);
|
KPPPStateMachine(KPPPInterface& interface);
|
||||||
~KPPPStateMachine();
|
~KPPPStateMachine();
|
||||||
|
|
||||||
// copies are not allowed!
|
// copies are not allowed!
|
||||||
KPPPStateMachine(const KPPPStateMachine& copy);
|
KPPPStateMachine(const KPPPStateMachine& copy);
|
||||||
KPPPStateMachine& operator= (const KPPPStateMachine& copy);
|
KPPPStateMachine& operator= (const KPPPStateMachine& copy);
|
||||||
@@ -42,28 +43,28 @@ class KPPPStateMachine {
|
|||||||
//! Returns the LCP protocol object belonging to this state machine.
|
//! Returns the LCP protocol object belonging to this state machine.
|
||||||
KPPPLCP& LCP() const
|
KPPPLCP& LCP() const
|
||||||
{ return fLCP; }
|
{ return fLCP; }
|
||||||
|
|
||||||
//! Returns the current state as defined in RFC 1661.
|
//! Returns the current state as defined in RFC 1661.
|
||||||
ppp_state State() const
|
ppp_state State() const
|
||||||
{ return fState; }
|
{ return fState; }
|
||||||
//! Returns the internal phase.
|
//! Returns the internal phase.
|
||||||
ppp_phase Phase() const
|
ppp_phase Phase() const
|
||||||
{ return fPhase; }
|
{ return fPhase; }
|
||||||
|
|
||||||
uint8 NextID();
|
uint8 NextID();
|
||||||
|
|
||||||
//! Sets our packets' magic number. Used by Link-Quality-Monitoring.
|
//! Sets our packets' magic number. Used by Link-Quality-Monitoring.
|
||||||
void SetMagicNumber(uint32 magicNumber)
|
void SetMagicNumber(uint32 magicNumber)
|
||||||
{ fMagicNumber = magicNumber; }
|
{ fMagicNumber = magicNumber; }
|
||||||
//! Returns our packets' magic number.
|
//! Returns our packets' magic number.
|
||||||
uint32 MagicNumber() const
|
uint32 MagicNumber() const
|
||||||
{ return fMagicNumber; }
|
{ return fMagicNumber; }
|
||||||
|
|
||||||
// public actions
|
// public actions
|
||||||
bool Reconfigure();
|
bool Reconfigure();
|
||||||
bool SendEchoRequest();
|
bool SendEchoRequest();
|
||||||
bool SendDiscardRequest();
|
bool SendDiscardRequest();
|
||||||
|
|
||||||
// public events:
|
// public events:
|
||||||
// NOTE: Local/PeerAuthenticationAccepted/Denied MUST be called before
|
// NOTE: Local/PeerAuthenticationAccepted/Denied MUST be called before
|
||||||
// Up(Failed)/DownEvent in order to allow changing the configuration of
|
// Up(Failed)/DownEvent in order to allow changing the configuration of
|
||||||
@@ -77,7 +78,7 @@ class KPPPStateMachine {
|
|||||||
//! Returns our local authentication status.
|
//! Returns our local authentication status.
|
||||||
ppp_authentication_status LocalAuthenticationStatus() const
|
ppp_authentication_status LocalAuthenticationStatus() const
|
||||||
{ return fLocalAuthenticationStatus; }
|
{ return fLocalAuthenticationStatus; }
|
||||||
|
|
||||||
void PeerAuthenticationRequested();
|
void PeerAuthenticationRequested();
|
||||||
void PeerAuthenticationAccepted(const char *name);
|
void PeerAuthenticationAccepted(const char *name);
|
||||||
void PeerAuthenticationDenied(const char *name);
|
void PeerAuthenticationDenied(const char *name);
|
||||||
@@ -87,17 +88,17 @@ class KPPPStateMachine {
|
|||||||
//! Returns the peer's authentication status.
|
//! Returns the peer's authentication status.
|
||||||
ppp_authentication_status PeerAuthenticationStatus() const
|
ppp_authentication_status PeerAuthenticationStatus() const
|
||||||
{ return fPeerAuthenticationStatus; }
|
{ return fPeerAuthenticationStatus; }
|
||||||
|
|
||||||
// sub-interface events
|
// sub-interface events
|
||||||
void UpFailedEvent(KPPPInterface& interface);
|
void UpFailedEvent(KPPPInterface& interface);
|
||||||
void UpEvent(KPPPInterface& interface);
|
void UpEvent(KPPPInterface& interface);
|
||||||
void DownEvent(KPPPInterface& interface);
|
void DownEvent(KPPPInterface& interface);
|
||||||
|
|
||||||
// protocol events
|
// protocol events
|
||||||
void UpFailedEvent(KPPPProtocol *protocol);
|
void UpFailedEvent(KPPPProtocol *protocol);
|
||||||
void UpEvent(KPPPProtocol *protocol);
|
void UpEvent(KPPPProtocol *protocol);
|
||||||
void DownEvent(KPPPProtocol *protocol);
|
void DownEvent(KPPPProtocol *protocol);
|
||||||
|
|
||||||
// device events
|
// device events
|
||||||
bool TLSNotify();
|
bool TLSNotify();
|
||||||
bool TLFNotify();
|
bool TLFNotify();
|
||||||
@@ -109,30 +110,30 @@ class KPPPStateMachine {
|
|||||||
// private StateMachine methods
|
// private StateMachine methods
|
||||||
void NewState(ppp_state next);
|
void NewState(ppp_state next);
|
||||||
void NewPhase(ppp_phase next);
|
void NewPhase(ppp_phase next);
|
||||||
|
|
||||||
// private events
|
// private events
|
||||||
void OpenEvent();
|
void OpenEvent();
|
||||||
void ContinueOpenEvent();
|
void ContinueOpenEvent();
|
||||||
void CloseEvent();
|
void CloseEvent();
|
||||||
void TOGoodEvent();
|
void TOGoodEvent();
|
||||||
void TOBadEvent();
|
void TOBadEvent();
|
||||||
void RCRGoodEvent(struct mbuf *packet);
|
void RCRGoodEvent(net_buffer *packet);
|
||||||
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject);
|
void RCRBadEvent(net_buffer *nak, net_buffer *reject);
|
||||||
void RCAEvent(struct mbuf *packet);
|
void RCAEvent(net_buffer *packet);
|
||||||
void RCNEvent(struct mbuf *packet);
|
void RCNEvent(net_buffer *packet);
|
||||||
void RTREvent(struct mbuf *packet);
|
void RTREvent(net_buffer *packet);
|
||||||
void RTAEvent(struct mbuf *packet);
|
void RTAEvent(net_buffer *packet);
|
||||||
void RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
void RUCEvent(net_buffer *packet, uint16 protocolNumber,
|
||||||
uint8 code = PPP_PROTOCOL_REJECT);
|
uint8 code = PPP_PROTOCOL_REJECT);
|
||||||
void RXJGoodEvent(struct mbuf *packet);
|
void RXJGoodEvent(net_buffer *packet);
|
||||||
void RXJBadEvent(struct mbuf *packet);
|
void RXJBadEvent(net_buffer *packet);
|
||||||
void RXREvent(struct mbuf *packet);
|
void RXREvent(net_buffer *packet);
|
||||||
|
|
||||||
// general events (for Good/Bad events)
|
// general events (for Good/Bad events)
|
||||||
void TimerEvent();
|
void TimerEvent();
|
||||||
void RCREvent(struct mbuf *packet);
|
void RCREvent(net_buffer *packet);
|
||||||
void RXJEvent(struct mbuf *packet);
|
void RXJEvent(net_buffer *packet);
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
void IllegalEvent(ppp_event event);
|
void IllegalEvent(ppp_event event);
|
||||||
void ThisLayerUp();
|
void ThisLayerUp();
|
||||||
@@ -142,42 +143,42 @@ class KPPPStateMachine {
|
|||||||
void InitializeRestartCount();
|
void InitializeRestartCount();
|
||||||
void ZeroRestartCount();
|
void ZeroRestartCount();
|
||||||
bool SendConfigureRequest();
|
bool SendConfigureRequest();
|
||||||
bool SendConfigureAck(struct mbuf *packet);
|
bool SendConfigureAck(net_buffer *packet);
|
||||||
bool SendConfigureNak(struct mbuf *packet);
|
bool SendConfigureNak(net_buffer *packet);
|
||||||
bool SendTerminateRequest();
|
bool SendTerminateRequest();
|
||||||
bool SendTerminateAck(struct mbuf *request = NULL);
|
bool SendTerminateAck(net_buffer *request = NULL);
|
||||||
bool SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code);
|
bool SendCodeReject(net_buffer *packet, uint16 protocolNumber, uint8 code);
|
||||||
bool SendEchoReply(struct mbuf *request);
|
bool SendEchoReply(net_buffer *request);
|
||||||
|
|
||||||
void BringProtocolsUp();
|
void BringProtocolsUp();
|
||||||
uint32 BringPhaseUp();
|
uint32 BringPhaseUp();
|
||||||
|
|
||||||
void DownProtocols();
|
void DownProtocols();
|
||||||
void ResetLCPHandlers();
|
void ResetLCPHandlers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KPPPInterface& fInterface;
|
KPPPInterface& fInterface;
|
||||||
KPPPLCP& fLCP;
|
KPPPLCP& fLCP;
|
||||||
|
|
||||||
ppp_state fState;
|
ppp_state fState;
|
||||||
ppp_phase fPhase;
|
ppp_phase fPhase;
|
||||||
|
|
||||||
vint32 fID;
|
int32 fID;
|
||||||
uint32 fMagicNumber;
|
uint32 fMagicNumber;
|
||||||
int32 fLastConnectionReportCode;
|
int32 fLastConnectionReportCode;
|
||||||
|
|
||||||
ppp_authentication_status fLocalAuthenticationStatus,
|
ppp_authentication_status fLocalAuthenticationStatus,
|
||||||
fPeerAuthenticationStatus;
|
fPeerAuthenticationStatus;
|
||||||
char *fLocalAuthenticationName, *fPeerAuthenticationName;
|
char *fLocalAuthenticationName, *fPeerAuthenticationName;
|
||||||
|
|
||||||
// counters and timers
|
// counters and timers
|
||||||
int32 fMaxRequest, fMaxTerminate, fMaxNak;
|
int32 fMaxRequest, fMaxTerminate, fMaxNak;
|
||||||
int32 fRequestCounter, fTerminateCounter, fNakCounter;
|
int32 fRequestCounter, fTerminateCounter, fNakCounter;
|
||||||
uint8 fRequestID, fTerminateID, fEchoID;
|
uint8 fRequestID, fTerminateID, fEchoID;
|
||||||
// the ID we used for the last configure/terminate/echo request
|
// the ID we used for the last configure/terminate/echo request
|
||||||
bigtime_t fNextTimeout;
|
bigtime_t fNextTimeout;
|
||||||
|
|
||||||
BLocker fLock;
|
mutex fLock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,76 @@
|
|||||||
#include <PPPDefs.h>
|
#include <PPPDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define IF_NAMESIZE 32
|
||||||
|
// copied from if.h
|
||||||
|
|
||||||
|
struct control_net_module_args {
|
||||||
|
char ifr_name[IF_NAMESIZE];
|
||||||
|
const char* name;
|
||||||
|
uint32 op;
|
||||||
|
void* data;
|
||||||
|
size_t length;
|
||||||
|
// union {
|
||||||
|
// struct sockaddr ifr_addr;
|
||||||
|
// struct sockaddr ifr_dstaddr;
|
||||||
|
// struct sockaddr ifr_broadaddr;
|
||||||
|
// struct sockaddr ifr_mask;
|
||||||
|
// struct ifreq_stats ifr_stats;
|
||||||
|
// struct route_entry ifr_route;
|
||||||
|
// int ifr_flags;
|
||||||
|
// int ifr_index;
|
||||||
|
// int ifr_metric;
|
||||||
|
// int ifr_mtu;
|
||||||
|
// int ifr_media;
|
||||||
|
// int ifr_type;
|
||||||
|
// int ifr_reqcap;
|
||||||
|
// int ifr_count;
|
||||||
|
// uint8_t* ifr_data;
|
||||||
|
// };
|
||||||
|
};
|
||||||
|
// copied from libppp
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// Paranoia mode: be far away of B_DEVICE_OP_CODES_END opcodes!!!
|
||||||
|
// You never know what another device driver ioctl() will do
|
||||||
|
// if think our NET_STACK_* is in fact his DO_RISKY_BUSINESS opcode, or whatever...
|
||||||
|
NET_IOCTL_BASE = 0xbe230000,
|
||||||
|
NET_STACK_IOCTL_BASE = NET_IOCTL_BASE + 0x200
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args *
|
||||||
|
NET_STACK_BIND, // sockaddr_args *
|
||||||
|
NET_STACK_RECVFROM, // struct msghdr *
|
||||||
|
NET_STACK_RECV, // transfer_args *
|
||||||
|
NET_STACK_SENDTO, // struct msghdr *
|
||||||
|
NET_STACK_SEND, // transfer_args *
|
||||||
|
NET_STACK_LISTEN, // int_args * (value = backlog)
|
||||||
|
NET_STACK_ACCEPT, // sockaddr_args *
|
||||||
|
NET_STACK_CONNECT, // sockaddr_args *
|
||||||
|
NET_STACK_SHUTDOWN, // int_args * (value = how)
|
||||||
|
NET_STACK_GETSOCKOPT, // sockopt_args *
|
||||||
|
NET_STACK_SETSOCKOPT, // sockopt_args *
|
||||||
|
NET_STACK_GETSOCKNAME, // sockaddr_args *
|
||||||
|
NET_STACK_GETPEERNAME, // sockaddr_args *
|
||||||
|
|
||||||
|
NET_STACK_SYSCTL, // sysctl_args *
|
||||||
|
NET_STACK_SELECT, // select_args *
|
||||||
|
NET_STACK_DESELECT, // select_args *
|
||||||
|
|
||||||
|
NET_STACK_GET_COOKIE, // void **
|
||||||
|
|
||||||
|
NET_STACK_STOP,
|
||||||
|
|
||||||
|
NET_STACK_NOTIFY_SOCKET_EVENT, // notify_socket_event_args * (userland stack only)
|
||||||
|
|
||||||
|
NET_STACK_CONTROL_NET_MODULE,
|
||||||
|
|
||||||
|
NET_STACK_IOCTL_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// various constants
|
// various constants
|
||||||
#define PPP_HANDLER_NAME_LENGTH_LIMIT 63
|
#define PPP_HANDLER_NAME_LENGTH_LIMIT 63
|
||||||
// if the name is longer than this value it will be truncated to fit the structure
|
// if the name is longer than this value it will be truncated to fit the structure
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
#include <directories.h>
|
#include <directories.h>
|
||||||
|
|
||||||
#include "net_module.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef uint32 ppp_interface_id;
|
typedef uint32 ppp_interface_id;
|
||||||
|
|
||||||
@@ -37,7 +35,8 @@ typedef uint32 ppp_interface_id;
|
|||||||
#define PPP_SERVER_MODE_VALUE "Server"
|
#define PPP_SERVER_MODE_VALUE "Server"
|
||||||
|
|
||||||
// path defines
|
// path defines
|
||||||
#define PPP_MODULES_PATH NETWORK_MODULES_ROOT "ppp"
|
#define NETWORK_MODULES_ROOT "network"
|
||||||
|
#define PPP_MODULES_PATH NETWORK_MODULES_ROOT "/ppp"
|
||||||
#define PTP_INTERFACE_SETTINGS_PATH \
|
#define PTP_INTERFACE_SETTINGS_PATH \
|
||||||
kUserSettingsDirectory "/kernel/drivers/ptpnet"
|
kUserSettingsDirectory "/kernel/drivers/ptpnet"
|
||||||
// TODO: should be: /etc/ptpnet
|
// TODO: should be: /etc/ptpnet
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef __PPP_DEV_H
|
||||||
|
#define __PPP_DEV_H
|
||||||
|
#include <net_device.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
|
#include <KPPPInterface.h>
|
||||||
|
|
||||||
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
struct ppp_device : net_device, DoublyLinkedListLinkImpl<ppp_device> {
|
||||||
|
KPPPInterface * KPPP_Interface;
|
||||||
|
uint32 frame_size;
|
||||||
|
net_fifo ppp_fifo;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -10,6 +10,7 @@ if $(TARGET_PLATFORM) != haiku {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||||
headers ] : true ;
|
headers ] : true ;
|
||||||
@@ -19,18 +20,18 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
|||||||
|
|
||||||
StaticLibrary libppp.a :
|
StaticLibrary libppp.a :
|
||||||
strlcat.c
|
strlcat.c
|
||||||
driver_settings.c
|
driver_settings.cpp
|
||||||
settings_tools.cpp
|
settings_tools.cpp
|
||||||
KPPPUtils.cpp
|
KPPPUtils.cpp
|
||||||
|
|
||||||
_libppputils.cpp
|
|
||||||
PPPInterface.cpp
|
PPPInterface.cpp
|
||||||
PPPInterfaceListener.cpp
|
PPPInterfaceListener.cpp
|
||||||
PPPManager.cpp
|
PPPManager.cpp
|
||||||
MessageDriverSettingsUtils.cpp
|
MessageDriverSettingsUtils.cpp
|
||||||
|
: libnetwork.so libbnetapi.so
|
||||||
;
|
;
|
||||||
|
|
||||||
SEARCH on [ FGristFiles strlcat.c ] = [ FDirName $(HAIKU_TOP) src system libroot posix string ] ;
|
SEARCH on [ FGristFiles strlcat.c ] = [ FDirName $(HAIKU_TOP) src system libroot posix string ] ;
|
||||||
SEARCH on [ FGristFiles driver_settings.c ] = [ FDirName $(HAIKU_TOP) src system libroot os ] ;
|
SEARCH on [ FGristFiles driver_settings.cpp ] = [ FDirName $(HAIKU_TOP) src system libroot os ] ;
|
||||||
SEARCH on [ FGristFiles settings_tools.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
|
SEARCH on [ FGristFiles settings_tools.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
|
||||||
SEARCH on [ FGristFiles KPPPUtils.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
|
SEARCH on [ FGristFiles KPPPUtils.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
|
||||||
|
|||||||
@@ -13,13 +13,20 @@
|
|||||||
#include "PPPInterface.h"
|
#include "PPPInterface.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cctype>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "_libppputils.h"
|
|
||||||
|
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include <NetworkDevice.h>
|
||||||
|
#include <NetworkInterface.h>
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Sets the interface to \a ID.
|
/*! \brief Sets the interface to \a ID.
|
||||||
|
|
||||||
@@ -27,7 +34,9 @@
|
|||||||
*/
|
*/
|
||||||
PPPInterface::PPPInterface(ppp_interface_id ID)
|
PPPInterface::PPPInterface(ppp_interface_id ID)
|
||||||
{
|
{
|
||||||
fFD = open(get_stack_driver_path(), O_RDWR);
|
// printf("direct constructor\n");
|
||||||
|
int family = AF_INET;
|
||||||
|
fFD = socket(family, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
SetTo(ID);
|
SetTo(ID);
|
||||||
}
|
}
|
||||||
@@ -36,7 +45,10 @@ PPPInterface::PPPInterface(ppp_interface_id ID)
|
|||||||
//! Copy constructor.
|
//! Copy constructor.
|
||||||
PPPInterface::PPPInterface(const PPPInterface& copy)
|
PPPInterface::PPPInterface(const PPPInterface& copy)
|
||||||
{
|
{
|
||||||
fFD = open(get_stack_driver_path(), O_RDWR);
|
// printf("Copy constructor\n");
|
||||||
|
// fFD = open(get_stack_driver_path(), O_RDWR);
|
||||||
|
int family = AF_INET;
|
||||||
|
fFD = socket(family, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
SetTo(copy.ID());
|
SetTo(copy.ID());
|
||||||
}
|
}
|
||||||
@@ -45,6 +57,7 @@ PPPInterface::PPPInterface(const PPPInterface& copy)
|
|||||||
//! Destructor.
|
//! Destructor.
|
||||||
PPPInterface::~PPPInterface()
|
PPPInterface::~PPPInterface()
|
||||||
{
|
{
|
||||||
|
// printf("Destructor\n");
|
||||||
if (fFD >= 0)
|
if (fFD >= 0)
|
||||||
close(fFD);
|
close(fFD);
|
||||||
}
|
}
|
||||||
@@ -64,6 +77,7 @@ PPPInterface::InitCheck() const
|
|||||||
{
|
{
|
||||||
if (fFD < 0)
|
if (fFD < 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if (fID == PPP_UNDEFINED_INTERFACE_ID)
|
if (fID == PPP_UNDEFINED_INTERFACE_ID)
|
||||||
return B_BAD_INDEX;
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
@@ -87,19 +101,29 @@ PPPInterface::InitCheck() const
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::SetTo(ppp_interface_id ID)
|
PPPInterface::SetTo(ppp_interface_id ID)
|
||||||
{
|
{
|
||||||
if (fFD < 0)
|
// printf("Set To %ld begin=============================\n", ID);
|
||||||
|
if (fFD < 0) {
|
||||||
|
printf("No fFD\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
fID = ID;
|
||||||
|
|
||||||
ppp_interface_info_t info;
|
ppp_interface_info_t info;
|
||||||
|
// printf("SetTo info:%p\n", &info);
|
||||||
if (GetInterfaceInfo(&info)) {
|
if (GetInterfaceInfo(&info)) {
|
||||||
fName = info.info.name;
|
fName = info.info.name;
|
||||||
fID = ID;
|
fID = ID;
|
||||||
|
// printf("%s fine: name:%s, fID:%ld\n", __func__, info.info.name, fID);
|
||||||
} else {
|
} else {
|
||||||
fName = "";
|
fName = "";
|
||||||
fID = PPP_UNDEFINED_INTERFACE_ID;
|
fID = PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
// printf("%s fail: name:%s, fID:%ld\n", __func__, "", fID);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printf("Set To %ld end =============================\n", ID);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,23 +143,32 @@ PPPInterface::SetTo(ppp_interface_id ID)
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::Control(uint32 op, void *data, size_t length) const
|
PPPInterface::Control(uint32 op, void *data, size_t length) const
|
||||||
{
|
{
|
||||||
if (InitCheck() != B_OK)
|
if (InitCheck() != B_OK) {
|
||||||
|
printf("%s:InitCheck fail\n", __func__);
|
||||||
return InitCheck();
|
return InitCheck();
|
||||||
|
}
|
||||||
ppp_control_info control;
|
|
||||||
|
ppp_control_info info;
|
||||||
control_net_module_args args;
|
control_net_module_args args;
|
||||||
|
|
||||||
|
sprintf(args.ifr_name, "%s", "ppp1");
|
||||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||||
args.op = PPPC_CONTROL_INTERFACE;
|
args.op = PPPC_CONTROL_INTERFACE;
|
||||||
args.data = &control;
|
args.data = &info;
|
||||||
args.length = sizeof(control);
|
args.length = sizeof(ppp_control_info);
|
||||||
|
|
||||||
control.index = ID();
|
info.index = ID();
|
||||||
control.op = op;
|
info.op = op;
|
||||||
control.data = data;
|
info.data = data;
|
||||||
control.length = length;
|
info.length = length;
|
||||||
|
|
||||||
return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args);
|
printf("PPPInterface::Control: ppp_control_info %p control_net_module_args %p data %p \n", &info, &args, data);
|
||||||
|
|
||||||
|
status_t status = ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args);
|
||||||
|
if (status != B_OK)
|
||||||
|
printf("%s:%s: fail\n", __FILE__, __func__);
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -143,6 +176,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length) const
|
|||||||
bool
|
bool
|
||||||
PPPInterface::SetUsername(const char *username) const
|
PPPInterface::SetUsername(const char *username) const
|
||||||
{
|
{
|
||||||
|
printf("PPPInterface::SetUsername\n");
|
||||||
if (InitCheck() != B_OK || !username)
|
if (InitCheck() != B_OK || !username)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -155,6 +189,7 @@ PPPInterface::SetUsername(const char *username) const
|
|||||||
bool
|
bool
|
||||||
PPPInterface::SetPassword(const char *password) const
|
PPPInterface::SetPassword(const char *password) const
|
||||||
{
|
{
|
||||||
|
printf("PPPInterface::SetPassword\n");
|
||||||
if (InitCheck() != B_OK || !password)
|
if (InitCheck() != B_OK || !password)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -167,6 +202,7 @@ PPPInterface::SetPassword(const char *password) const
|
|||||||
bool
|
bool
|
||||||
PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
|
PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
|
||||||
{
|
{
|
||||||
|
printf("PPPInterface::SetAskBeforeConnecting\n");
|
||||||
if (InitCheck() != B_OK)
|
if (InitCheck() != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -188,6 +224,7 @@ PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
|
|||||||
status_t
|
status_t
|
||||||
PPPInterface::GetSettingsEntry(BEntry *entry) const
|
PPPInterface::GetSettingsEntry(BEntry *entry) const
|
||||||
{
|
{
|
||||||
|
printf("PPPInterface::GetSettingsEntry\n");
|
||||||
if (InitCheck() != B_OK)
|
if (InitCheck() != B_OK)
|
||||||
return InitCheck();
|
return InitCheck();
|
||||||
else if (!entry || strlen(Name()) == 0)
|
else if (!entry || strlen(Name()) == 0)
|
||||||
@@ -205,10 +242,103 @@ PPPInterface::GetSettingsEntry(BEntry *entry) const
|
|||||||
bool
|
bool
|
||||||
PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
|
PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
|
||||||
{
|
{
|
||||||
|
// printf("%s info at:%p", __func__, info);
|
||||||
|
if (InitCheck() != B_OK || !info) {
|
||||||
|
// printf("InitCheck fail %s info at:%p", __func__, info);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Control(PPPC_GET_INTERFACE_INFO, info, sizeof(ppp_interface_info_t))
|
||||||
|
== B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PPPInterface::ControlDevice(ppp_device_info_t *info) const
|
||||||
|
{
|
||||||
|
// printf("%s info at:%p", __func__, info);
|
||||||
if (InitCheck() != B_OK || !info)
|
if (InitCheck() != B_OK || !info)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return Control(PPPC_GET_INTERFACE_INFO, &info, sizeof(ppp_interface_info_t))
|
ppp_control_info controlInfo;
|
||||||
|
controlInfo.op = PPPC_GET_DEVICE_INFO;
|
||||||
|
controlInfo.index = 0;
|
||||||
|
controlInfo.data = info;
|
||||||
|
controlInfo.length = sizeof(ppp_device_info_t);
|
||||||
|
|
||||||
|
return Control(PPPC_CONTROL_DEVICE, &controlInfo, sizeof(ppp_control_info))
|
||||||
|
== B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PPPInterface::ControlOptionHandler(ppp_simple_handler_info_t *info, uint32 handlerindex, uint32 handlerOP) const
|
||||||
|
{
|
||||||
|
// printf("%s info at:%p", __func__, info);
|
||||||
|
if (InitCheck() != B_OK || !info)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ppp_control_info controlInfo;
|
||||||
|
controlInfo.index = handlerindex;
|
||||||
|
controlInfo.op = handlerOP;
|
||||||
|
controlInfo.data = info;
|
||||||
|
controlInfo.length = sizeof(ppp_simple_handler_info_t);
|
||||||
|
|
||||||
|
return Control(PPPC_CONTROL_OPTION_HANDLER, &controlInfo, sizeof(ppp_control_info))
|
||||||
|
== B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PPPInterface::ControlChild(void *info, uint32 childindex, uint32 childOP) const
|
||||||
|
{
|
||||||
|
// printf("%s info at:%p", __func__, info);
|
||||||
|
if (InitCheck() != B_OK || !info)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ppp_control_info controlInfo;
|
||||||
|
controlInfo.index = childindex;
|
||||||
|
controlInfo.op = childOP;
|
||||||
|
controlInfo.data = info;
|
||||||
|
// controlInfo.length = sizeof(ppp_simple_handler_info_t);
|
||||||
|
|
||||||
|
return Control(PPPC_CONTROL_CHILD, &controlInfo, sizeof(ppp_control_info))
|
||||||
|
== B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PPPInterface::ControlLCPExtension(ppp_simple_handler_info_t *info, uint32 LCPExtensionindex, uint32 LCPExtensionOP) const
|
||||||
|
{
|
||||||
|
// printf("%s info at:%p", __func__, info);
|
||||||
|
if (InitCheck() != B_OK || !info)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ppp_control_info controlInfo;
|
||||||
|
controlInfo.index = LCPExtensionindex;
|
||||||
|
controlInfo.op = LCPExtensionOP;
|
||||||
|
controlInfo.data = info;
|
||||||
|
controlInfo.length = sizeof(ppp_simple_handler_info_t);
|
||||||
|
|
||||||
|
return Control(PPPC_CONTROL_LCP_EXTENSION, &controlInfo, sizeof(ppp_control_info))
|
||||||
|
== B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PPPInterface::ControlProtocol(ppp_protocol_info_t *info, uint32 protocolindex, uint32 protocolOP) const
|
||||||
|
{
|
||||||
|
// printf("%s info at:%p", __func__, info);
|
||||||
|
if (InitCheck() != B_OK || !info)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ppp_control_info controlInfo;
|
||||||
|
controlInfo.index = protocolindex;
|
||||||
|
controlInfo.op = protocolOP;
|
||||||
|
controlInfo.data = info;
|
||||||
|
controlInfo.length = sizeof(ppp_protocol_info_t);
|
||||||
|
|
||||||
|
return Control(PPPC_CONTROL_PROTOCOL, &controlInfo, sizeof(ppp_control_info))
|
||||||
== B_OK;
|
== B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +352,7 @@ PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
|
|||||||
bool
|
bool
|
||||||
PPPInterface::GetStatistics(ppp_statistics *statistics) const
|
PPPInterface::GetStatistics(ppp_statistics *statistics) const
|
||||||
{
|
{
|
||||||
|
printf("PPPInterface::GetStatistics\n");
|
||||||
if (!statistics)
|
if (!statistics)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -233,6 +364,7 @@ PPPInterface::GetStatistics(ppp_statistics *statistics) const
|
|||||||
bool
|
bool
|
||||||
PPPInterface::HasSettings(const driver_settings *settings) const
|
PPPInterface::HasSettings(const driver_settings *settings) const
|
||||||
{
|
{
|
||||||
|
printf("PPPInterface::HasSettings\n");
|
||||||
if (InitCheck() != B_OK || !settings)
|
if (InitCheck() != B_OK || !settings)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -250,9 +382,24 @@ PPPInterface::Up() const
|
|||||||
{
|
{
|
||||||
if (InitCheck() != B_OK)
|
if (InitCheck() != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
BNetworkInterface interface(Name());
|
||||||
|
if (!interface.Exists())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int32 currentFlags = interface.Flags();
|
||||||
|
currentFlags |= IFF_UP;
|
||||||
|
|
||||||
|
status_t status = interface.SetFlags(currentFlags);
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
int32 id = ID();
|
int32 id = ID();
|
||||||
control_net_module_args args;
|
control_net_module_args args;
|
||||||
|
sprintf(args.ifr_name, "%s", "ppp1");
|
||||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||||
args.op = PPPC_BRING_INTERFACE_UP;
|
args.op = PPPC_BRING_INTERFACE_UP;
|
||||||
args.data = &id;
|
args.data = &id;
|
||||||
@@ -268,9 +415,24 @@ PPPInterface::Down() const
|
|||||||
{
|
{
|
||||||
if (InitCheck() != B_OK)
|
if (InitCheck() != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
BNetworkInterface interface(Name());
|
||||||
|
if (!interface.Exists())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int32 currentFlags = interface.Flags();
|
||||||
|
currentFlags &= ~IFF_UP;
|
||||||
|
|
||||||
|
status_t status = interface.SetFlags(currentFlags);
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
int32 id = ID();
|
int32 id = ID();
|
||||||
control_net_module_args args;
|
control_net_module_args args;
|
||||||
|
sprintf(args.ifr_name, "%s", "ppp1");
|
||||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||||
args.op = PPPC_BRING_INTERFACE_DOWN;
|
args.op = PPPC_BRING_INTERFACE_DOWN;
|
||||||
args.data = &id;
|
args.data = &id;
|
||||||
@@ -292,6 +454,7 @@ bool
|
|||||||
PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
|
PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
|
||||||
int32 flags) const
|
int32 flags) const
|
||||||
{
|
{
|
||||||
|
printf("PPPInterface::EnableReports\n");
|
||||||
ppp_report_request request;
|
ppp_report_request request;
|
||||||
request.type = type;
|
request.type = type;
|
||||||
request.thread = thread;
|
request.thread = thread;
|
||||||
@@ -311,6 +474,7 @@ PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
|
|||||||
bool
|
bool
|
||||||
PPPInterface::DisableReports(ppp_report_type type, thread_id thread) const
|
PPPInterface::DisableReports(ppp_report_type type, thread_id thread) const
|
||||||
{
|
{
|
||||||
|
printf("PPPInterface::DisableReports\n");
|
||||||
ppp_report_request request;
|
ppp_report_request request;
|
||||||
request.type = type;
|
request.type = type;
|
||||||
request.thread = thread;
|
request.thread = thread;
|
||||||
|
|||||||
@@ -20,16 +20,49 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstdio>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <settings_tools.h>
|
#include <settings_tools.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "_libppputils.h"
|
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include <net/if_media.h>
|
||||||
|
#include <net/if_types.h>
|
||||||
|
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
#include <NetworkDevice.h>
|
||||||
|
#include <NetworkInterface.h>
|
||||||
|
#include <NetworkRoster.h>
|
||||||
|
|
||||||
|
#include <NetServer.h>
|
||||||
|
|
||||||
//! Constructor. Does nothing special.
|
//! Constructor. Does nothing special.
|
||||||
PPPManager::PPPManager()
|
PPPManager::PPPManager()
|
||||||
{
|
{
|
||||||
fFD = open(get_stack_driver_path(), O_RDWR);
|
// fFD = open(get_stack_driver_path(), O_RDWR);
|
||||||
|
int family = AF_INET;
|
||||||
|
|
||||||
|
fFD = socket(family, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
// FileDescriptorCloser closer(socket);
|
||||||
|
|
||||||
|
// ifaliasreq request;
|
||||||
|
// strlcpy(request.ifra_name, name, IF_NAMESIZE);
|
||||||
|
// request.ifra_index = address.Index();
|
||||||
|
// request.ifra_flags = address.Flags();
|
||||||
|
|
||||||
|
// memcpy(&request.ifra_addr, &address.Address().SockAddr(),
|
||||||
|
// address.Address().Length());
|
||||||
|
// memcpy(&request.ifra_mask, &address.Mask().SockAddr(),
|
||||||
|
// address.Mask().Length());
|
||||||
|
// memcpy(&request.ifra_broadaddr, &address.Broadcast().SockAddr(),
|
||||||
|
// address.Broadcast().Length());
|
||||||
|
|
||||||
|
// if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0)
|
||||||
|
// return errno;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -133,6 +166,7 @@ PPPManager::Control(uint32 op, void *data, size_t length) const
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
control_net_module_args args;
|
control_net_module_args args;
|
||||||
|
sprintf(args.ifr_name, "%s", "ppp1");
|
||||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||||
args.op = op;
|
args.op = op;
|
||||||
args.data = data;
|
args.data = data;
|
||||||
@@ -169,6 +203,7 @@ PPPManager::ControlModule(const char *name, uint32 op, void *data,
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
control_net_module_args args;
|
control_net_module_args args;
|
||||||
|
sprintf(args.ifr_name, "%s", "ppp1");
|
||||||
args.name = name;
|
args.name = name;
|
||||||
args.op = op;
|
args.op = op;
|
||||||
args.data = data;
|
args.data = data;
|
||||||
@@ -207,13 +242,72 @@ PPPManager::CreateInterface(const driver_settings *settings) const
|
|||||||
ppp_interface_id
|
ppp_interface_id
|
||||||
PPPManager::CreateInterfaceWithName(const char *name) const
|
PPPManager::CreateInterfaceWithName(const char *name) const
|
||||||
{
|
{
|
||||||
ppp_interface_description_info info;
|
ppp_interface_id ID = InterfaceWithName(name);
|
||||||
info.u.name = name;
|
|
||||||
|
if (ID != PPP_UNDEFINED_INTERFACE_ID)
|
||||||
|
return ID;
|
||||||
|
|
||||||
|
BNetworkInterface interface(name);
|
||||||
|
if (!interface.Exists()) {
|
||||||
|
// the interface does not exist yet, we have to add it first
|
||||||
|
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||||
|
|
||||||
|
status_t status = roster.AddInterface(interface);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "PPPManager::CreateInterfaceWithName: Could not add interface: %s\n",
|
||||||
|
strerror(status));
|
||||||
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return InterfaceWithName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
|
||||||
|
// ppp_interface_description_info info;
|
||||||
|
// info.u.name = name;
|
||||||
|
//
|
||||||
|
// if (Control(PPPC_CREATE_INTERFACE_WITH_NAME, &info, sizeof(info)) != B_OK)
|
||||||
|
// return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
// else
|
||||||
|
// return info.interface;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! It will remove the complete interface with all
|
||||||
|
of its addresses.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
delete_interface(const char* name)
|
||||||
|
{
|
||||||
|
BNetworkInterface interface(name);
|
||||||
|
|
||||||
|
// Delete interface
|
||||||
|
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||||
|
|
||||||
|
status_t status = roster.RemoveInterface(interface);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "delete_interface: Could not delete interface %s\n",
|
||||||
|
name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Deletes the interface with the given \a name.
|
||||||
|
bool
|
||||||
|
PPPManager::DeleteInterface(const char* name) const
|
||||||
|
{
|
||||||
|
ppp_interface_id ID = InterfaceWithName(name);
|
||||||
|
|
||||||
|
if (ID == PPP_UNDEFINED_INTERFACE_ID)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return delete_interface(name);
|
||||||
|
|
||||||
if (Control(PPPC_CREATE_INTERFACE_WITH_NAME, &info, sizeof(info)) != B_OK)
|
|
||||||
return PPP_UNDEFINED_INTERFACE_ID;
|
|
||||||
else
|
|
||||||
return info.interface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -253,18 +347,22 @@ PPPManager::Interfaces(int32 *count,
|
|||||||
// loop until we get all interfaces
|
// loop until we get all interfaces
|
||||||
while (true) {
|
while (true) {
|
||||||
requestCount = *count = CountInterfaces(filter);
|
requestCount = *count = CountInterfaces(filter);
|
||||||
if (*count == -1)
|
if (*count <= 0) {
|
||||||
|
printf("No interface, count, first round:%ld\n", *count);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
requestCount += 10;
|
requestCount += 10;
|
||||||
// request some more interfaces in case some are added in the mean time
|
// request some more interfaces in case some are added in the mean time
|
||||||
interfaces = new ppp_interface_id[requestCount];
|
interfaces = new ppp_interface_id[requestCount];
|
||||||
|
// printf("interfaces addr: %p\n, requestCount: %ld", interfaces, requestCount);
|
||||||
*count = GetInterfaces(interfaces, requestCount, filter);
|
*count = GetInterfaces(interfaces, requestCount, filter);
|
||||||
if (*count == -1) {
|
if (*count <= 0) {
|
||||||
|
printf("No interface, count second round:%ld\n", *count);
|
||||||
delete interfaces;
|
delete interfaces;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*count < requestCount)
|
if (*count < requestCount)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -345,12 +443,17 @@ PPPManager::InterfaceWithName(const char *name) const
|
|||||||
int32 count;
|
int32 count;
|
||||||
ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
|
ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
|
||||||
|
|
||||||
if (!interfaces)
|
if (!interfaces || count <= 0) {
|
||||||
|
printf("ERROR: Could not get ppp name:%s\n", name);
|
||||||
return PPP_UNDEFINED_INTERFACE_ID;
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("first ID:%ld count:%ld\n", interfaces[0], count);
|
||||||
|
|
||||||
ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
|
ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
|
||||||
PPPInterface interface;
|
PPPInterface interface;
|
||||||
ppp_interface_info_t info;
|
ppp_interface_info_t info;
|
||||||
|
// printf("internal info is at: %p\n", &info);
|
||||||
|
|
||||||
for (int32 index = 0; index < count; index++) {
|
for (int32 index = 0; index < count; index++) {
|
||||||
interface.SetTo(interfaces[index]);
|
interface.SetTo(interfaces[index]);
|
||||||
@@ -374,11 +477,79 @@ PPPManager::InterfaceWithName(const char *name) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns the number of existing interfaces or a negative value on error.
|
||||||
|
bool
|
||||||
|
is_ppp_interface(const char* name)
|
||||||
|
{
|
||||||
|
// size_t length = strlen(name);
|
||||||
|
// if (length < 8)
|
||||||
|
// putchar('\t');
|
||||||
|
// else
|
||||||
|
// printf("\n\t");
|
||||||
|
|
||||||
|
// get link level interface for this interface
|
||||||
|
|
||||||
|
BNetworkInterface interface(name);
|
||||||
|
BNetworkAddress linkAddress;
|
||||||
|
status_t status = interface.GetHardwareAddress(linkAddress);
|
||||||
|
if (status == B_OK) {
|
||||||
|
// const char *type = "unknown";
|
||||||
|
switch (linkAddress.LinkLevelType()) {
|
||||||
|
case IFT_ETHER:
|
||||||
|
// type = "Ethernet";
|
||||||
|
// printf("%s\n", type);
|
||||||
|
break;
|
||||||
|
case IFT_LOOP:
|
||||||
|
// type = "Local Loopback";
|
||||||
|
// printf("%s\n", type);
|
||||||
|
break;
|
||||||
|
case IFT_MODEM:
|
||||||
|
// type = "Modem";
|
||||||
|
// printf("%s\n", type);
|
||||||
|
break;
|
||||||
|
case IFT_PPP:
|
||||||
|
// type = "PPP";
|
||||||
|
// printf("%s\n", type);
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// printf("%s\n", type);
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns the number of ppp interfaces
|
||||||
|
int32
|
||||||
|
count_ppp_interface(void)
|
||||||
|
{
|
||||||
|
int32 count = 0;
|
||||||
|
|
||||||
|
// get a list of all ppp interfaces
|
||||||
|
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||||
|
|
||||||
|
BNetworkInterface interface;
|
||||||
|
uint32 cookie = 0;
|
||||||
|
|
||||||
|
while (roster.GetNextInterface(&cookie, interface) == B_OK) {
|
||||||
|
if (is_ppp_interface(interface.Name()))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Returns the number of existing interfaces or a negative value on error.
|
//! Returns the number of existing interfaces or a negative value on error.
|
||||||
int32
|
int32
|
||||||
PPPManager::CountInterfaces(ppp_interface_filter filter) const
|
PPPManager::CountInterfaces(ppp_interface_filter filter) const
|
||||||
{
|
{
|
||||||
return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter));
|
// return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter));
|
||||||
|
return count_ppp_interface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <OS.h>
|
|
||||||
#include "_libppputils.h"
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
|
|
||||||
char*
|
|
||||||
get_stack_driver_path()
|
|
||||||
{
|
|
||||||
char *path;
|
|
||||||
|
|
||||||
// user-defined stack driver path?
|
|
||||||
path = getenv("NET_STACK_DRIVER_PATH");
|
|
||||||
if (path)
|
|
||||||
return path;
|
|
||||||
|
|
||||||
// use the default stack driver path
|
|
||||||
return NET_STACK_DRIVER_PATH;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __libppputils__h
|
|
||||||
#define __libppputils__h
|
|
||||||
|
|
||||||
#include <net_stack_driver.h>
|
|
||||||
|
|
||||||
|
|
||||||
char *get_stack_driver_path();
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -39,6 +39,12 @@ class PPPInterface {
|
|||||||
bool GetInterfaceInfo(ppp_interface_info_t *info) const;
|
bool GetInterfaceInfo(ppp_interface_info_t *info) const;
|
||||||
bool GetStatistics(ppp_statistics *statistics) const;
|
bool GetStatistics(ppp_statistics *statistics) const;
|
||||||
bool HasSettings(const driver_settings *settings) const;
|
bool HasSettings(const driver_settings *settings) const;
|
||||||
|
|
||||||
|
bool ControlDevice(ppp_device_info_t *info) const;
|
||||||
|
bool ControlProtocol(ppp_protocol_info_t *info, uint32 protocolindex, uint32 procotolOP) const;
|
||||||
|
bool ControlOptionHandler(ppp_simple_handler_info_t *info, uint32 handlerindex, uint32 handlerOP) const;
|
||||||
|
bool ControlLCPExtension(ppp_simple_handler_info_t *info, uint32 LCPExtensionindex, uint32 LCPExtensionOP) const;
|
||||||
|
bool ControlChild(void *info, uint32 childindex, uint32 childOP) const;
|
||||||
|
|
||||||
bool Up() const;
|
bool Up() const;
|
||||||
bool Down() const;
|
bool Down() const;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#ifndef _PPP_MANAGER__H
|
#ifndef _PPP_MANAGER__H
|
||||||
#define _PPP_MANAGER__H
|
#define _PPP_MANAGER__H
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
#include <KPPPManager.h>
|
#include <KPPPManager.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ class PPPManager {
|
|||||||
ppp_interface_id CreateInterface(const driver_settings *settings) const;
|
ppp_interface_id CreateInterface(const driver_settings *settings) const;
|
||||||
ppp_interface_id CreateInterfaceWithName(const char *name) const;
|
ppp_interface_id CreateInterfaceWithName(const char *name) const;
|
||||||
bool DeleteInterface(ppp_interface_id ID) const;
|
bool DeleteInterface(ppp_interface_id ID) const;
|
||||||
|
bool DeleteInterface(const char* name) const;
|
||||||
|
|
||||||
ppp_interface_id *Interfaces(int32 *count,
|
ppp_interface_id *Interfaces(int32 *count,
|
||||||
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const;
|
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const;
|
||||||
|
|||||||
@@ -833,6 +833,9 @@ init_stack()
|
|||||||
// TODO: for now!
|
// TODO: for now!
|
||||||
register_domain_datalink_protocols(AF_INET, IFT_LOOP,
|
register_domain_datalink_protocols(AF_INET, IFT_LOOP,
|
||||||
"network/datalink_protocols/loopback_frame/v1", NULL);
|
"network/datalink_protocols/loopback_frame/v1", NULL);
|
||||||
|
// add ppp datalink protocol
|
||||||
|
register_domain_datalink_protocols(AF_INET, IFT_PPP,
|
||||||
|
"network/datalink_protocols/ppp_frame/v1", NULL);
|
||||||
register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
|
register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
|
||||||
"network/datalink_protocols/loopback_frame/v1", NULL);
|
"network/datalink_protocols/loopback_frame/v1", NULL);
|
||||||
register_domain_datalink_protocols(AF_INET, IFT_ETHER,
|
register_domain_datalink_protocols(AF_INET, IFT_ETHER,
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ SubInclude HAIKU_TOP src bin network ftpd ;
|
|||||||
SubInclude HAIKU_TOP src bin network ifconfig ;
|
SubInclude HAIKU_TOP src bin network ifconfig ;
|
||||||
SubInclude HAIKU_TOP src bin network mount_nfs ;
|
SubInclude HAIKU_TOP src bin network mount_nfs ;
|
||||||
SubInclude HAIKU_TOP src bin network netstat ;
|
SubInclude HAIKU_TOP src bin network netstat ;
|
||||||
#SubInclude HAIKU_TOP src bin network pppconfig ;
|
SubInclude HAIKU_TOP src bin network pppconfig ;
|
||||||
#SubInclude HAIKU_TOP src bin network ppp_up ;
|
SubInclude HAIKU_TOP src bin network ppp_up ;
|
||||||
SubInclude HAIKU_TOP src bin network ping ;
|
SubInclude HAIKU_TOP src bin network ping ;
|
||||||
SubInclude HAIKU_TOP src bin network ping6 ;
|
SubInclude HAIKU_TOP src bin network ping6 ;
|
||||||
SubInclude HAIKU_TOP src bin network route ;
|
SubInclude HAIKU_TOP src bin network route ;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
SubDir HAIKU_TOP src bin ppp_up ;
|
SubDir HAIKU_TOP src bin network ppp_up ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
||||||
|
|
||||||
@@ -8,7 +8,10 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
UsePrivateHeaders net ;
|
UsePrivateKernelHeaders ;
|
||||||
|
UsePrivateHeaders net app libroot shared interface libbe be root tracker textencoding
|
||||||
|
root ;
|
||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||||
headers ] : true ;
|
headers ] : true ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
@@ -24,7 +27,7 @@ BinCommand ppp_up :
|
|||||||
PPPStatusWindow.cpp
|
PPPStatusWindow.cpp
|
||||||
PPPUpApplication.cpp
|
PPPUpApplication.cpp
|
||||||
:
|
:
|
||||||
libppp.a be
|
libppp.a be $(TARGET_LIBSUPC++) translation $(HAIKU_LOCALE_LIBS) root $(TARGET_NETWORK_LIBS)
|
||||||
;
|
;
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
#ifndef STATUS_VIEW__H
|
#ifndef STATUS_VIEW__H
|
||||||
#define STATUS_VIEW__H
|
#define STATUS_VIEW__H
|
||||||
|
|
||||||
#include <View.h>
|
#include <Button.h>
|
||||||
#include <PPPInterface.h>
|
#include <PPPInterface.h>
|
||||||
|
#include <StringView.h>
|
||||||
|
|
||||||
|
|
||||||
class PPPStatusView : public BView {
|
class PPPStatusView : public BView {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
SubDir HAIKU_TOP src bin pppconfig ;
|
SubDir HAIKU_TOP src bin network pppconfig ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||||
headers ] : true ;
|
headers ] : true ;
|
||||||
@@ -17,7 +18,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
|||||||
BinCommand pppconfig :
|
BinCommand pppconfig :
|
||||||
pppconfig.cpp
|
pppconfig.cpp
|
||||||
:
|
:
|
||||||
be libppp.a
|
be libppp.a $(TARGET_LIBSUPC++) $(TARGET_NETWORK_LIBS)
|
||||||
;
|
;
|
||||||
|
|
||||||
# Installation -- in the test directory for the time being
|
# Installation -- in the test directory for the time being
|
||||||
|
|||||||
@@ -40,33 +40,35 @@ status_t
|
|||||||
show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
||||||
{
|
{
|
||||||
PPPManager manager;
|
PPPManager manager;
|
||||||
if(manager.InitCheck() != B_OK) {
|
if (manager.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 count;
|
int32 count = 0;
|
||||||
ppp_interface_id *interfaces = manager.Interfaces(&count, filter);
|
ppp_interface_id *interfaces = manager.Interfaces(&count, filter);
|
||||||
|
|
||||||
if(!interfaces) {
|
if (!interfaces || count <= 0) {
|
||||||
fprintf(stderr, "Error: Could not get interfaces information!\n");
|
fprintf(stderr, "Error: Could not get interfaces information!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Get %ld ppp interfaces, first is %ld!\n", count, interfaces[0]);
|
||||||
|
|
||||||
ppp_interface_info_t info;
|
ppp_interface_info_t info;
|
||||||
PPPInterface interface;
|
PPPInterface interface;
|
||||||
|
|
||||||
printf("Listing PPP interfaces:\n");
|
printf("Listing PPP interfaces:\n");
|
||||||
|
|
||||||
// print out information for each interface
|
// print out information for each interface
|
||||||
for(int32 index = 0; index < count; index++) {
|
for (int32 index = 0; index < count; index++) {
|
||||||
interface.SetTo(interfaces[index]);
|
interface.SetTo(interfaces[index]);
|
||||||
if(interface.InitCheck() == B_OK) {
|
if (interface.InitCheck() == B_OK) {
|
||||||
interface.GetInterfaceInfo(&info);
|
interface.GetInterfaceInfo(&info);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// type and unit (if it has one)
|
// type and unit (if it has one)
|
||||||
if(info.info.if_unit >= 0) {
|
if (info.info.if_unit >= 0) {
|
||||||
printf("Type: Visible\n");
|
printf("Type: Visible\n");
|
||||||
printf("\tInterface: ppp%ld\n", info.info.if_unit);
|
printf("\tInterface: ppp%ld\n", info.info.if_unit);
|
||||||
} else
|
} else
|
||||||
@@ -79,9 +81,9 @@ show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
|||||||
|
|
||||||
// mode
|
// mode
|
||||||
printf("\tMode: ");
|
printf("\tMode: ");
|
||||||
if(info.info.mode == PPP_CLIENT_MODE)
|
if (info.info.mode == PPP_CLIENT_MODE)
|
||||||
printf("Client\n");
|
printf("Client\n");
|
||||||
else if(info.info.mode == PPP_SERVER_MODE)
|
else if (info.info.mode == PPP_SERVER_MODE)
|
||||||
printf("Server\n");
|
printf("Server\n");
|
||||||
else
|
else
|
||||||
printf("Unknown\n");
|
printf("Unknown\n");
|
||||||
@@ -118,13 +120,13 @@ status_t
|
|||||||
create(const char *name, bool bringUp = true)
|
create(const char *name, bool bringUp = true)
|
||||||
{
|
{
|
||||||
PPPManager manager;
|
PPPManager manager;
|
||||||
if(manager.InitCheck() != B_OK) {
|
if (manager.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPPInterface interface(manager.CreateInterfaceWithName(name));
|
PPPInterface interface(manager.CreateInterfaceWithName(name));
|
||||||
if(interface.InitCheck() != B_OK) {
|
if (interface.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not create interface: %s!\n", name);
|
fprintf(stderr, "Error: Could not create interface: %s!\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -134,13 +136,13 @@ create(const char *name, bool bringUp = true)
|
|||||||
ppp_interface_info_t info;
|
ppp_interface_info_t info;
|
||||||
interface.GetInterfaceInfo(&info);
|
interface.GetInterfaceInfo(&info);
|
||||||
|
|
||||||
if(info.info.if_unit >= 0)
|
if (info.info.if_unit >= 0)
|
||||||
printf("Interface: ppp%ld\n", info.info.if_unit);
|
printf("Interface: ppp%ld\n", info.info.if_unit);
|
||||||
else
|
else
|
||||||
printf("This interface is hidden! You can delete it by typing:\n"
|
printf("This interface is hidden! You can delete it by typing:\n"
|
||||||
"pppconfig delete %ld\n", interface.ID());
|
"pppconfig delete %ld\n", interface.ID());
|
||||||
|
|
||||||
if(bringUp) {
|
if (bringUp) {
|
||||||
interface.Up();
|
interface.Up();
|
||||||
printf("Connecting in background...\n");
|
printf("Connecting in background...\n");
|
||||||
}
|
}
|
||||||
@@ -153,22 +155,22 @@ static
|
|||||||
status_t
|
status_t
|
||||||
connect(const char *name)
|
connect(const char *name)
|
||||||
{
|
{
|
||||||
if(!name || strlen(name) == 0)
|
if (!name || strlen(name) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
PPPManager manager;
|
PPPManager manager;
|
||||||
if(manager.InitCheck() != B_OK) {
|
if (manager.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPPInterface interface(manager.InterfaceWithName(name));
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
if(interface.InitCheck() != B_OK) {
|
if (interface.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!interface.Up()) {
|
if (!interface.Up()) {
|
||||||
fprintf(stderr, "Error: Could not connect!\n");
|
fprintf(stderr, "Error: Could not connect!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -181,24 +183,435 @@ connect(const char *name)
|
|||||||
|
|
||||||
static
|
static
|
||||||
status_t
|
status_t
|
||||||
disconnect(const char *name)
|
setuser(const char *name, const char* user)
|
||||||
{
|
{
|
||||||
if(!name || strlen(name) == 0)
|
if (!name || strlen(name) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (!user || strlen(user) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
PPPManager manager;
|
PPPManager manager;
|
||||||
if(manager.InitCheck() != B_OK) {
|
if (manager.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPPInterface interface(manager.InterfaceWithName(name));
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
if(interface.InitCheck() != B_OK) {
|
if (interface.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!interface.Down()) {
|
if (!interface.SetUsername(user)) {
|
||||||
|
fprintf(stderr, "Error: Could not SetUsername %s!\n", user);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
setpass(const char *name, const char* pass)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!pass || strlen(pass) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interface.SetPassword(pass)) {
|
||||||
|
fprintf(stderr, "Error: Could not SetUsername %s!\n", pass);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
setaskbeforeconnect(const char *name, const char* connect)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bool askBeforeConnecting = false;
|
||||||
|
if (connect || !strcmp(connect, "true") || !strcmp(connect, "ask") ||
|
||||||
|
!strcmp(connect, "yes") || !strcmp(connect, "y"))
|
||||||
|
askBeforeConnecting = true;
|
||||||
|
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interface.SetAskBeforeConnecting(askBeforeConnecting)) {
|
||||||
|
fprintf(stderr, "Error: Could not connect %s!\n", connect);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
getstatistics(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_statistics pppStatistics;
|
||||||
|
if (interface.GetStatistics(&pppStatistics) != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not getstatistics: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
hassettings(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
driver_settings settings;
|
||||||
|
if (interface.HasSettings(&settings) != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not getstatistics: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
enablereports(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_report_type type = PPP_ALL_REPORTS;
|
||||||
|
thread_id thread = 0;
|
||||||
|
int32 flags = 0;
|
||||||
|
|
||||||
|
if (interface.EnableReports(type, thread, flags) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not EnableReports: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
disablereports(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_report_type type = PPP_ALL_REPORTS;
|
||||||
|
thread_id thread = 0;
|
||||||
|
|
||||||
|
if (interface.DisableReports(type, thread) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not EnableReports: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
controlchild(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_simple_handler_info_t info;
|
||||||
|
|
||||||
|
if (interface.ControlChild(&info, 0, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("LCPExtensionHandler: %s\n", info.info.name);
|
||||||
|
printf("isEnabled: %d\n", info.info.isEnabled);
|
||||||
|
|
||||||
|
if (interface.ControlChild(&info, 0, PPPC_ENABLE) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
controllcpextension(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_simple_handler_info_t info;
|
||||||
|
|
||||||
|
if (interface.ControlLCPExtension(&info, 1, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("LCPExtensionHandler: %s\n", info.info.name);
|
||||||
|
printf("isEnabled: %d\n", info.info.isEnabled);
|
||||||
|
|
||||||
|
if (interface.ControlLCPExtension(&info, 1, PPPC_ENABLE) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
controloptionhandler(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_simple_handler_info_t info;
|
||||||
|
|
||||||
|
if (interface.ControlOptionHandler(&info, 0, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("protocol: %s\n", info.info.name);
|
||||||
|
printf("isEnabled: %d\n", info.info.isEnabled);
|
||||||
|
|
||||||
|
if (interface.ControlOptionHandler(&info, 0, PPPC_ENABLE) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
controlprotocol(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_protocol_info_t info;
|
||||||
|
|
||||||
|
if (interface.ControlProtocol(&info, 0, PPPC_GET_PROTOCOL_INFO) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not PPPC_GET_PROTOCOL_INFO: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("protocol: %s\n", info.info.name);
|
||||||
|
printf("type: %s\n", info.info.type);
|
||||||
|
printf("activationPhase: %d\n", info.info.activationPhase);
|
||||||
|
printf("addressFamily: %ld\n", info.info.addressFamily);
|
||||||
|
printf("flags: %ld\n", info.info.flags);
|
||||||
|
printf("side: %d\n", info.info.side);
|
||||||
|
printf("level: %d\n", info.info.level);
|
||||||
|
printf("connectionPhase: %d\n", info.info.connectionPhase);
|
||||||
|
printf("protocolNumber: %d\n", info.info.protocolNumber);
|
||||||
|
printf("isEnabled: %d\n", info.info.isEnabled);
|
||||||
|
printf("isUpRequested: %d\n", info.info.isUpRequested);
|
||||||
|
|
||||||
|
if (interface.ControlProtocol(&info, 0, PPPC_ENABLE) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
controldevice(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_device_info_t info;
|
||||||
|
|
||||||
|
if (interface.ControlDevice(&info) != true) {
|
||||||
|
fprintf(stderr, "Error: Could not ControlDevice: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("name: %s\n", info.info.name);
|
||||||
|
printf("MTU: %ld\n", info.info.MTU);
|
||||||
|
printf("inputTransferRate: %ld\n", info.info.inputTransferRate);
|
||||||
|
printf("outputTransferRate: %ld\n", info.info.outputTransferRate);
|
||||||
|
printf("outputBytesCount: %ld\n", info.info.outputBytesCount);
|
||||||
|
printf("isUp: %d\n", info.info.isUp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
disconnect(const char *name)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
PPPManager manager;
|
||||||
|
if (manager.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(manager.InterfaceWithName(name));
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interface.Down()) {
|
||||||
fprintf(stderr, "Error: Could not disconnect!\n");
|
fprintf(stderr, "Error: Could not disconnect!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -211,16 +624,16 @@ static
|
|||||||
status_t
|
status_t
|
||||||
delete_interface(const char *name)
|
delete_interface(const char *name)
|
||||||
{
|
{
|
||||||
if(!name || strlen(name) == 0)
|
if (!name || strlen(name) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
PPPManager manager;
|
PPPManager manager;
|
||||||
if(manager.InitCheck() != B_OK) {
|
if (manager.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!manager.DeleteInterface(manager.InterfaceWithName(name))) {
|
if (!manager.DeleteInterface(name)) {
|
||||||
fprintf(stderr, "Error: Could not delete interface!\n");
|
fprintf(stderr, "Error: Could not delete interface!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -233,26 +646,33 @@ static
|
|||||||
status_t
|
status_t
|
||||||
show_details(const char *name)
|
show_details(const char *name)
|
||||||
{
|
{
|
||||||
if(!name || strlen(name) == 0)
|
if (!name || strlen(name) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
PPPManager manager;
|
PPPManager manager;
|
||||||
if(manager.InitCheck() != B_OK) {
|
if (manager.InitCheck() != B_OK) {
|
||||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPPInterface interface(manager.InterfaceWithName(name));
|
ppp_interface_id ID = manager.InterfaceWithName(name);
|
||||||
if(interface.InitCheck() != B_OK) {
|
if (ID <= 0) {
|
||||||
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PPPInterface interface(ID);
|
||||||
|
if (interface.InitCheck() != B_OK) {
|
||||||
|
fprintf(stderr, "Error: Could not find interface ID: %ld!\n", ID);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ppp_interface_info_t info;
|
ppp_interface_info_t info;
|
||||||
|
// printf("ppp_interface_info_t addr:%p\n", &info);
|
||||||
interface.GetInterfaceInfo(&info);
|
interface.GetInterfaceInfo(&info);
|
||||||
|
|
||||||
// type and name (if it has one)
|
// type and name (if it has one)
|
||||||
if(info.info.if_unit >= 0) {
|
if (info.info.if_unit >= 0) {
|
||||||
printf("Type: Visible\n");
|
printf("Type: Visible\n");
|
||||||
printf("Interface: ppp%ld\n", info.info.if_unit);
|
printf("Interface: ppp%ld\n", info.info.if_unit);
|
||||||
} else
|
} else
|
||||||
@@ -277,9 +697,9 @@ show_details(const char *name)
|
|||||||
|
|
||||||
// mode
|
// mode
|
||||||
printf("Mode: ");
|
printf("Mode: ");
|
||||||
if(info.info.mode == PPP_CLIENT_MODE)
|
if (info.info.mode == PPP_CLIENT_MODE)
|
||||||
printf("Client\n");
|
printf("Client\n");
|
||||||
else if(info.info.mode == PPP_SERVER_MODE)
|
else if (info.info.mode == PPP_SERVER_MODE)
|
||||||
printf("Server\n");
|
printf("Server\n");
|
||||||
else
|
else
|
||||||
printf("Unknown\n");
|
printf("Unknown\n");
|
||||||
@@ -310,24 +730,51 @@ show_details(const char *name)
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if(argc == 2) {
|
if (argc == 2) {
|
||||||
if(!strcmp(argv[1], "show") || !strcmp(argv[1], "-a"))
|
if (!strcmp(argv[1], "show") || !strcmp(argv[1], "-a"))
|
||||||
return show(PPP_ALL_INTERFACES);
|
return show(PPP_ALL_INTERFACES);
|
||||||
else
|
else
|
||||||
return print_help();
|
return print_help();
|
||||||
}if(argc == 3) {
|
}if (argc == 3) {
|
||||||
if(!strcmp(argv[1], "init"))
|
if (!strcmp(argv[1], "init"))
|
||||||
return create(argv[2], false);
|
return create(argv[2], false);
|
||||||
else if(!strcmp(argv[1], "create"))
|
else if (!strcmp(argv[1], "create"))
|
||||||
return create(argv[2], true);
|
return create(argv[2], true);
|
||||||
else if(!strcmp(argv[1], "connect"))
|
else if (!strcmp(argv[1], "connect"))
|
||||||
return connect(argv[2]);
|
return connect(argv[2]);
|
||||||
else if(!strcmp(argv[1], "disconnect"))
|
else if (!strcmp(argv[1], "disconnect"))
|
||||||
return disconnect(argv[2]);
|
return disconnect(argv[2]);
|
||||||
else if(!strcmp(argv[1], "delete"))
|
else if (!strcmp(argv[1], "delete"))
|
||||||
return delete_interface(argv[2]);
|
return delete_interface(argv[2]);
|
||||||
else if(!strcmp(argv[1], "details"))
|
else if (!strcmp(argv[1], "details"))
|
||||||
return show_details(argv[2]);
|
return show_details(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "getstatistics"))
|
||||||
|
return getstatistics(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "hassettings"))
|
||||||
|
return hassettings(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "enablereports"))
|
||||||
|
return enablereports(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "disablereports"))
|
||||||
|
return disablereports(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controldevice"))
|
||||||
|
return controldevice(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controlprotocol"))
|
||||||
|
return controlprotocol(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controloptionhandler"))
|
||||||
|
return controloptionhandler(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controllcpextension"))
|
||||||
|
return controllcpextension(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controlchild"))
|
||||||
|
return controlchild(argv[2]);
|
||||||
|
else
|
||||||
|
return print_help();
|
||||||
|
} if (argc == 4) {
|
||||||
|
if (!strcmp(argv[1], "setuser"))
|
||||||
|
return setuser(argv[2], argv[3]);
|
||||||
|
else if (!strcmp(argv[1], "setpass"))
|
||||||
|
return setpass(argv[2], argv[3]);
|
||||||
|
else if (!strcmp(argv[1], "setaskbeforeconnect"))
|
||||||
|
return setaskbeforeconnect(argv[2], argv[3]);
|
||||||
else
|
else
|
||||||
return print_help();
|
return print_help();
|
||||||
} else
|
} else
|
||||||
|
|||||||
Reference in New Issue
Block a user