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
|
||||
;
|
||||
|
||||
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe ;
|
||||
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe KPPPManager ;
|
||||
|
||||
SYSTEM_NETWORK_PROTOCOLS =
|
||||
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 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
|
||||
: $(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 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
|
||||
: $(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 protocols ;
|
||||
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 ;
|
||||
|
||||
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 pppoe ;
|
||||
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 ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
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.
|
||||
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||
# Needed for the atomic_add64() prototype.
|
||||
}
|
||||
|
||||
# for kernel_cpp.h and BLocker
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : 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 libroot net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
|
||||
{
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
}
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp pppoe
|
||||
] : true ;
|
||||
|
||||
KernelAddon ipcp :
|
||||
# imported from libnet
|
||||
atomic.S
|
||||
kernel_cpp.cpp
|
||||
|
||||
# imported from kernel util
|
||||
inet_addr.c
|
||||
|
||||
|
||||
ipcp.cpp
|
||||
Protocol.cpp
|
||||
;
|
||||
|
||||
|
||||
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 ;
|
||||
|
||||
# Installation
|
||||
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
||||
: /boot/home/config/add-ons/kernel/network/ppp
|
||||
: ipcp ;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,9 +9,11 @@
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <KPPPProtocol.h>
|
||||
#include <Locker.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net_datalink.h>
|
||||
#include <net_datalink_protocol.h>
|
||||
#include <net/route.h>
|
||||
|
||||
|
||||
#define IPCP_PROTOCOL 0x8021
|
||||
@@ -60,46 +62,46 @@ class IPCP : public KPPPProtocol {
|
||||
public:
|
||||
IPCP(KPPPInterface& interface, driver_parameter *settings);
|
||||
virtual ~IPCP();
|
||||
|
||||
|
||||
virtual void Uninit();
|
||||
|
||||
|
||||
ppp_state State() const
|
||||
{ return fState; }
|
||||
|
||||
|
||||
virtual status_t StackControl(uint32 op, void *data);
|
||||
|
||||
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
virtual status_t Send(struct mbuf *packet,
|
||||
|
||||
virtual status_t Send(net_buffer *packet,
|
||||
uint16 protocolNumber = IPCP_PROTOCOL);
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
||||
status_t ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||
status_t ReceiveIPPacket(net_buffer *packet, uint16 protocolNumber);
|
||||
virtual void Pulse();
|
||||
|
||||
private:
|
||||
bool ParseSideRequests(const driver_parameter *requests, ppp_side side);
|
||||
void UpdateAddresses();
|
||||
void RemoveRoutes();
|
||||
|
||||
|
||||
// for state machine
|
||||
void NewState(ppp_state next);
|
||||
uint8 NextID();
|
||||
// return the next id for IPCP packets
|
||||
|
||||
|
||||
// events
|
||||
void TOGoodEvent();
|
||||
void TOBadEvent();
|
||||
void RCREvent(struct mbuf *packet);
|
||||
void RCRGoodEvent(struct mbuf *packet);
|
||||
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject);
|
||||
void RCAEvent(struct mbuf *packet);
|
||||
void RCNEvent(struct mbuf *packet);
|
||||
void RTREvent(struct mbuf *packet);
|
||||
void RTAEvent(struct mbuf *packet);
|
||||
void RUCEvent(struct mbuf *packet);
|
||||
void RXJBadEvent(struct mbuf *packet);
|
||||
|
||||
void RCREvent(net_buffer *packet);
|
||||
void RCRGoodEvent(net_buffer *packet);
|
||||
void RCRBadEvent(net_buffer *nak, net_buffer *reject);
|
||||
void RCAEvent(net_buffer *packet);
|
||||
void RCNEvent(net_buffer *packet);
|
||||
void RTREvent(net_buffer *packet);
|
||||
void RTAEvent(net_buffer *packet);
|
||||
void RUCEvent(net_buffer *packet);
|
||||
void RXJBadEvent(net_buffer *packet);
|
||||
|
||||
// actions
|
||||
void IllegalEvent(ppp_event event);
|
||||
void ReportUpFailedEvent();
|
||||
@@ -108,27 +110,27 @@ class IPCP : public KPPPProtocol {
|
||||
void InitializeRestartCount();
|
||||
void ResetRestartCount();
|
||||
bool SendConfigureRequest();
|
||||
bool SendConfigureAck(struct mbuf *packet);
|
||||
bool SendConfigureNak(struct mbuf *packet);
|
||||
bool SendConfigureAck(net_buffer *packet);
|
||||
bool SendConfigureNak(net_buffer *packet);
|
||||
bool SendTerminateRequest();
|
||||
bool SendTerminateAck(struct mbuf *request = NULL);
|
||||
bool SendCodeReject(struct mbuf *packet);
|
||||
bool SendTerminateAck(net_buffer *request = NULL);
|
||||
bool SendCodeReject(net_buffer *packet);
|
||||
|
||||
private:
|
||||
ipcp_configuration fLocalConfiguration, fPeerConfiguration;
|
||||
ipcp_requests fLocalRequests, fPeerRequests;
|
||||
|
||||
|
||||
// default route
|
||||
struct sockaddr_in fGateway;
|
||||
rtentry *fDefaultRoute;
|
||||
|
||||
net_route *fDefaultRoute;
|
||||
|
||||
// used for local requests
|
||||
bool fRequestPrimaryDNS, fRequestSecondaryDNS;
|
||||
|
||||
|
||||
// for state machine
|
||||
ppp_state fState;
|
||||
vint32 fID;
|
||||
|
||||
int32 fID;
|
||||
|
||||
// counters and timers
|
||||
int32 fMaxRequest, fMaxTerminate, fMaxNak;
|
||||
int32 fRequestCounter, fTerminateCounter, fNakCounter;
|
||||
|
||||
@@ -5,21 +5,24 @@
|
||||
|
||||
#include <KernelExport.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 <KPPPModule.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, ...);
|
||||
|
||||
net_stack_module_info *gStackModule = NULL;
|
||||
net_buffer_module_info *gBufferModule = NULL;
|
||||
|
||||
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// TODO: Remove isascii() (needed for inet_aton()) when our kernel is finished!
|
||||
@@ -28,7 +31,7 @@ extern "C"
|
||||
int
|
||||
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
|
||||
|
||||
@@ -38,22 +41,22 @@ bool
|
||||
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
||||
driver_parameter *settings, ppp_module_key_type type)
|
||||
{
|
||||
if(type != PPP_PROTOCOL_KEY_TYPE)
|
||||
if (type != PPP_PROTOCOL_KEY_TYPE)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
IPCP *ipcp;
|
||||
bool success;
|
||||
if(subInterface) {
|
||||
if (subInterface) {
|
||||
ipcp = new IPCP(*subInterface, settings);
|
||||
success = subInterface->AddProtocol(ipcp);
|
||||
} else {
|
||||
ipcp = new IPCP(mainInterface, settings);
|
||||
success = mainInterface.AddProtocol(ipcp);
|
||||
}
|
||||
|
||||
|
||||
TRACE("IPCP: add_to(): %s\n",
|
||||
success && ipcp && ipcp->InitCheck() == B_OK ? "OK" : "ERROR");
|
||||
|
||||
|
||||
return success && ipcp && ipcp->InitCheck() == B_OK;
|
||||
}
|
||||
|
||||
@@ -71,24 +74,30 @@ static ppp_module_info ipcp_module = {
|
||||
|
||||
_EXPORT
|
||||
status_t
|
||||
std_ops(int32 op, ...)
|
||||
std_ops(int32 op, ...)
|
||||
{
|
||||
switch(op) {
|
||||
switch (op) {
|
||||
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;
|
||||
memset(gProto, 0, sizeof(struct protosw*) * IPPROTO_MAX);
|
||||
add_protosw(gProto, NET_LAYER1);
|
||||
return B_OK;
|
||||
|
||||
if (get_module(NET_BUFFER_MODULE_NAME,
|
||||
(module_info **)&gBufferModule) != B_OK) {
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
break;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
break;
|
||||
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp pap ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
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.
|
||||
}
|
||||
|
||||
# for kernel_cpp.h and BLocker
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
|
||||
{
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
}
|
||||
|
||||
|
||||
KernelAddon pap :
|
||||
pap.cpp
|
||||
Protocol.cpp
|
||||
@@ -31,5 +25,5 @@ LinkAgainst pap : libkernelppp.a ;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
||||
: /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||
: pap ;
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
#include <cstring>
|
||||
#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;
|
||||
// 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
|
||||
PAPHandler::AddToRequest(KPPPConfigurePacket& request)
|
||||
{
|
||||
// only local authenticators send requests to peer
|
||||
if(Owner().Side() != PPP_PEER_SIDE)
|
||||
if (Owner().Side() != PPP_PEER_SIDE)
|
||||
return B_OK;
|
||||
|
||||
|
||||
authentication_item item;
|
||||
item.type = kAuthenticationType;
|
||||
item.length = sizeof(item);
|
||||
item.protocolNumber = htons(PAP_PROTOCOL);
|
||||
|
||||
|
||||
request.AddItem((ppp_configure_item*) &item);
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -57,15 +65,15 @@ PAPHandler::ParseRequest(const KPPPConfigurePacket& request,
|
||||
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject)
|
||||
{
|
||||
// only local authenticators handle requests from peer
|
||||
if(Owner().Side() != PPP_LOCAL_SIDE)
|
||||
if (Owner().Side() != PPP_LOCAL_SIDE)
|
||||
return B_OK;
|
||||
|
||||
|
||||
// we merely check if the values are correct
|
||||
authentication_item *item = (authentication_item*) request.ItemAt(index);
|
||||
if(item->type != kAuthenticationType
|
||||
if (item->type != kAuthenticationType
|
||||
|| item->length != 4 || ntohs(item->protocolNumber) != PAP_PROTOCOL)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -92,9 +100,9 @@ PAP::~PAP()
|
||||
status_t
|
||||
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 KPPPProtocol::InitCheck();
|
||||
}
|
||||
|
||||
@@ -103,14 +111,14 @@ bool
|
||||
PAP::Up()
|
||||
{
|
||||
TRACE("PAP: Up() state=%d\n", State());
|
||||
|
||||
switch(State()) {
|
||||
|
||||
switch (State()) {
|
||||
case INITIAL:
|
||||
if(Side() == PPP_LOCAL_SIDE) {
|
||||
if (Side() == PPP_LOCAL_SIDE) {
|
||||
NewState(REQ_SENT);
|
||||
InitializeRestartCount();
|
||||
SendRequest();
|
||||
} else if(Side() == PPP_PEER_SIDE) {
|
||||
} else if (Side() == PPP_PEER_SIDE) {
|
||||
NewState(WAITING_FOR_REQ);
|
||||
InitializeRestartCount();
|
||||
fNextTimeout = system_time() + kPAPTimeout;
|
||||
@@ -119,11 +127,11 @@ PAP::Up()
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -132,8 +140,8 @@ bool
|
||||
PAP::Down()
|
||||
{
|
||||
TRACE("PAP: Down() state=%d\n", State());
|
||||
|
||||
switch(Interface().Phase()) {
|
||||
|
||||
switch (Interface().Phase()) {
|
||||
case PPP_DOWN_PHASE:
|
||||
// interface finished terminating
|
||||
case PPP_ESTABLISHED_PHASE:
|
||||
@@ -141,82 +149,83 @@ PAP::Down()
|
||||
NewState(INITIAL);
|
||||
DownEvent();
|
||||
break;
|
||||
|
||||
|
||||
/* case PPP_TERMINATION_PHASE:
|
||||
// interface is terminating
|
||||
break;
|
||||
|
||||
|
||||
case PPP_ESTABLISHMENT_PHASE:
|
||||
// interface is reconfiguring
|
||||
break;
|
||||
*/
|
||||
*/
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PAP::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
PAP::Send(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PAP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
PAP::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
if(!packet)
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
|
||||
if(protocolNumber != PAP_PROTOCOL)
|
||||
|
||||
if (protocolNumber != PAP_PROTOCOL)
|
||||
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:
|
||||
// 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;
|
||||
// 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)
|
||||
return PPP_UNHANDLED;
|
||||
|
||||
|
||||
// remove padding
|
||||
int32 length = packet->m_len;
|
||||
if(packet->m_flags & M_PKTHDR)
|
||||
length = packet->m_pkthdr.len;
|
||||
length -= ntohs(data->length);
|
||||
if(length)
|
||||
m_adj(packet, -length);
|
||||
|
||||
if(ntohs(data->length) < 4)
|
||||
int32 length = packet->size;
|
||||
length -= ntohs(data.length);
|
||||
|
||||
if (ntohs(data.length) < 4)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
// packet is freed by event methods
|
||||
// code values are the same as for LCP (but very reduced)
|
||||
switch(data->code) {
|
||||
switch (data.code) {
|
||||
case PPP_CONFIGURE_REQUEST:
|
||||
RREvent(packet);
|
||||
break;
|
||||
|
||||
|
||||
case PPP_CONFIGURE_ACK:
|
||||
RAEvent(packet);
|
||||
break;
|
||||
|
||||
|
||||
case PPP_CONFIGURE_NAK:
|
||||
RNEvent(packet);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return PPP_UNHANDLED;
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -224,19 +233,19 @@ PAP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
void
|
||||
PAP::Pulse()
|
||||
{
|
||||
if(fNextTimeout == 0 || fNextTimeout > system_time())
|
||||
if (fNextTimeout == 0 || fNextTimeout > system_time())
|
||||
return;
|
||||
fNextTimeout = 0;
|
||||
|
||||
switch(State()) {
|
||||
|
||||
switch (State()) {
|
||||
case REQ_SENT:
|
||||
case WAITING_FOR_REQ:
|
||||
if(fRequestCounter <= 0)
|
||||
if (fRequestCounter <= 0)
|
||||
TOBadEvent();
|
||||
else
|
||||
TOGoodEvent();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
@@ -254,22 +263,22 @@ void
|
||||
PAP::NewState(pap_state next)
|
||||
{
|
||||
TRACE("PAP: NewState(%d) state=%d\n", next, State());
|
||||
|
||||
|
||||
// state changes
|
||||
if(State() == INITIAL && next != State()) {
|
||||
if(Side() == PPP_LOCAL_SIDE)
|
||||
if (State() == INITIAL && next != State()) {
|
||||
if (Side() == PPP_LOCAL_SIDE)
|
||||
Interface().StateMachine().LocalAuthenticationRequested();
|
||||
else if(Side() == PPP_PEER_SIDE)
|
||||
else if (Side() == PPP_PEER_SIDE)
|
||||
Interface().StateMachine().PeerAuthenticationRequested();
|
||||
|
||||
|
||||
UpStarted();
|
||||
} else if(State() == ACCEPTED && next != State())
|
||||
} else if (State() == ACCEPTED && next != State())
|
||||
DownStarted();
|
||||
|
||||
|
||||
// maybe we do not need the timer anymore
|
||||
if(next == INITIAL || next == ACCEPTED)
|
||||
if (next == INITIAL || next == ACCEPTED)
|
||||
fNextTimeout = 0;
|
||||
|
||||
|
||||
fState = next;
|
||||
}
|
||||
|
||||
@@ -278,16 +287,16 @@ void
|
||||
PAP::TOGoodEvent()
|
||||
{
|
||||
TRACE("PAP: TOGoodEvent() state=%d\n", State());
|
||||
|
||||
switch(State()) {
|
||||
|
||||
switch (State()) {
|
||||
case REQ_SENT:
|
||||
SendRequest();
|
||||
break;
|
||||
|
||||
|
||||
case WAITING_FOR_REQ:
|
||||
fNextTimeout = system_time() + kPAPTimeout;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
@@ -298,21 +307,21 @@ void
|
||||
PAP::TOBadEvent()
|
||||
{
|
||||
TRACE("PAP: TOBadEvent() state=%d\n", State());
|
||||
|
||||
switch(State()) {
|
||||
|
||||
switch (State()) {
|
||||
case REQ_SENT:
|
||||
case WAITING_FOR_REQ:
|
||||
NewState(INITIAL);
|
||||
if(State() == REQ_SENT)
|
||||
if (State() == REQ_SENT)
|
||||
Interface().StateMachine().LocalAuthenticationDenied(
|
||||
Interface().Username());
|
||||
else
|
||||
Interface().StateMachine().PeerAuthenticationDenied(
|
||||
Interface().Username());
|
||||
|
||||
|
||||
UpFailedEvent();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
@@ -320,27 +329,30 @@ PAP::TOBadEvent()
|
||||
|
||||
|
||||
void
|
||||
PAP::RREvent(struct mbuf *packet)
|
||||
PAP::RREvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("PAP: RREvent() state=%d\n", State());
|
||||
|
||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
||||
int32 length = ntohs(request->length);
|
||||
uint8 *data = request->data;
|
||||
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return;
|
||||
ppp_lcp_packet &request = bufferheader.Data();
|
||||
int32 length = ntohs(request.length);
|
||||
uint8 *data = request.data;
|
||||
uint8 *userLength = data;
|
||||
uint8 *passwordLength = data + 1 + data[0];
|
||||
|
||||
|
||||
// make sure the length values are all okay
|
||||
if(6 + *userLength + *passwordLength > length) {
|
||||
m_freem(packet);
|
||||
if (6 + *userLength + *passwordLength > length) {
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
char *peerUsername = (char*) userLength + 1,
|
||||
*peerPassword = (char*) passwordLength + 1;
|
||||
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(peerPassword, password, *passwordLength)) {
|
||||
NewState(ACCEPTED);
|
||||
@@ -357,60 +369,68 @@ PAP::RREvent(struct mbuf *packet)
|
||||
|
||||
|
||||
void
|
||||
PAP::RAEvent(struct mbuf *packet)
|
||||
PAP::RAEvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
// TODO: log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(State()) {
|
||||
|
||||
switch (State()) {
|
||||
case REQ_SENT:
|
||||
NewState(ACCEPTED);
|
||||
Interface().StateMachine().LocalAuthenticationAccepted(
|
||||
Interface().Username());
|
||||
UpEvent();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PAP::RNEvent(struct mbuf *packet)
|
||||
PAP::RNEvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
// TODO: log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(State()) {
|
||||
|
||||
switch (State()) {
|
||||
case REQ_SENT:
|
||||
NewState(INITIAL);
|
||||
Interface().StateMachine().LocalAuthenticationDenied(
|
||||
Interface().Username());
|
||||
UpFailedEvent();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
@@ -425,72 +445,76 @@ bool
|
||||
PAP::SendRequest()
|
||||
{
|
||||
TRACE("PAP: SendRequest() state=%d\n", State());
|
||||
|
||||
|
||||
--fRequestCounter;
|
||||
fNextTimeout = system_time() + kPAPTimeout;
|
||||
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
if(!packet)
|
||||
|
||||
net_buffer *packet = gBufferModule->create(256);
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
|
||||
ppp_lcp_packet *request;
|
||||
gBufferModule->append_size(packet, 1492, (void **)&request);
|
||||
|
||||
const char *username = Interface().Username(), *password = Interface().Password();
|
||||
|
||||
packet->m_pkthdr.len = packet->m_len = 6 + strlen(username) + strlen(password);
|
||||
|
||||
// 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*);
|
||||
uint16 packcketLenth = 6 + strlen(username) + strlen(password);
|
||||
// 6 : lcp header 4 byte + username length 1 byte + password length 1 byte
|
||||
|
||||
request->code = PPP_CONFIGURE_REQUEST;
|
||||
request->id = fRequestID = NextID();
|
||||
request->length = htons(packet->m_len);
|
||||
request->length = htons(packcketLenth);
|
||||
uint8 *data = request->data;
|
||||
data[0] = strlen(username);
|
||||
memcpy(data + 1, username, strlen(username));
|
||||
data[1 + data[0]] = strlen(password);
|
||||
memcpy(data + 2 + data[0], password, strlen(password));
|
||||
|
||||
|
||||
gBufferModule->trim(packet, packcketLenth);
|
||||
|
||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PAP::SendAck(struct mbuf *packet)
|
||||
PAP::SendAck(net_buffer *packet)
|
||||
{
|
||||
TRACE("PAP: SendAck() state=%d\n", State());
|
||||
|
||||
if(!packet)
|
||||
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet *ack = mtod(packet, ppp_lcp_packet*);
|
||||
ack->code = PPP_CONFIGURE_ACK;
|
||||
packet->m_len = 5;
|
||||
if(packet->m_flags & M_PKTHDR)
|
||||
packet->m_pkthdr.len = 5;
|
||||
ack->length = htons(packet->m_len);
|
||||
|
||||
ack->data[0] = 0;
|
||||
|
||||
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return false;
|
||||
ppp_lcp_packet &ack = bufferheader.Data();
|
||||
|
||||
ack.code = PPP_CONFIGURE_ACK;
|
||||
ack.length = htons(5);
|
||||
ack.data[0] = 0;
|
||||
gBufferModule->trim(packet, 5);
|
||||
|
||||
bufferheader.Sync();
|
||||
|
||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PAP::SendNak(struct mbuf *packet)
|
||||
PAP::SendNak(net_buffer *packet)
|
||||
{
|
||||
TRACE("PAP: SendNak() state=%d\n", State());
|
||||
|
||||
if(!packet)
|
||||
ERROR("PAP: SendNak() state=%d\n", State());
|
||||
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
|
||||
nak->code = PPP_CONFIGURE_NAK;
|
||||
packet->m_len = 5;
|
||||
if(packet->m_flags & M_PKTHDR)
|
||||
packet->m_pkthdr.len = 5;
|
||||
nak->length = htons(packet->m_len);
|
||||
|
||||
nak->data[0] = 0;
|
||||
|
||||
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return false;
|
||||
ppp_lcp_packet &nak = bufferheader.Data();
|
||||
nak.code = PPP_CONFIGURE_NAK;
|
||||
nak.length = htons(5);
|
||||
nak.data[0] = 0;
|
||||
gBufferModule->trim(packet, 5);
|
||||
|
||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
||||
}
|
||||
|
||||
@@ -31,11 +31,12 @@ class PAP;
|
||||
class PAPHandler : public KPPPOptionHandler {
|
||||
public:
|
||||
PAPHandler(PAP& owner, KPPPInterface& interface);
|
||||
|
||||
|
||||
PAP& Owner() const
|
||||
{ return fOwner; }
|
||||
|
||||
|
||||
virtual status_t AddToRequest(KPPPConfigurePacket& request);
|
||||
virtual status_t SendingAck(const KPPPConfigurePacket&);
|
||||
virtual status_t ParseRequest(const KPPPConfigurePacket& request,
|
||||
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject);
|
||||
|
||||
@@ -48,17 +49,17 @@ class PAP : public KPPPProtocol {
|
||||
public:
|
||||
PAP(KPPPInterface& interface, driver_parameter *settings);
|
||||
virtual ~PAP();
|
||||
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
|
||||
pap_state State() const
|
||||
{ return fState; }
|
||||
|
||||
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
||||
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber);
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||
virtual void Pulse();
|
||||
|
||||
private:
|
||||
@@ -66,28 +67,28 @@ class PAP : public KPPPProtocol {
|
||||
void NewState(pap_state next);
|
||||
uint8 NextID();
|
||||
// return the next id for PAP packets
|
||||
|
||||
|
||||
// events
|
||||
void TOGoodEvent();
|
||||
void TOBadEvent();
|
||||
void RREvent(struct mbuf *packet);
|
||||
void RAEvent(struct mbuf *packet);
|
||||
void RNEvent(struct mbuf *packet);
|
||||
|
||||
void RREvent(net_buffer *packet);
|
||||
void RAEvent(net_buffer *packet);
|
||||
void RNEvent(net_buffer *packet);
|
||||
|
||||
// actions
|
||||
void ReportUpFailedEvent();
|
||||
void ReportUpEvent();
|
||||
void ReportDownEvent();
|
||||
void InitializeRestartCount();
|
||||
bool SendRequest();
|
||||
bool SendAck(struct mbuf *packet);
|
||||
bool SendNak(struct mbuf *packet);
|
||||
bool SendAck(net_buffer *packet);
|
||||
bool SendNak(net_buffer *packet);
|
||||
|
||||
private:
|
||||
// for state machine
|
||||
pap_state fState;
|
||||
vint32 fID;
|
||||
|
||||
int32 fID;
|
||||
|
||||
// counters and timers
|
||||
int32 fMaxRequest;
|
||||
int32 fRequestCounter;
|
||||
|
||||
@@ -5,42 +5,41 @@
|
||||
|
||||
#include <KernelExport.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 <KPPPModule.h>
|
||||
|
||||
#include "Protocol.h"
|
||||
|
||||
#define PAP_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/pap"
|
||||
|
||||
#define PAP_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pap"
|
||||
|
||||
struct core_module_info *core = NULL;
|
||||
net_stack_module_info *gStackModule = NULL;
|
||||
net_buffer_module_info *gBufferModule = NULL;
|
||||
status_t std_ops(int32 op, ...);
|
||||
|
||||
|
||||
static
|
||||
bool
|
||||
static bool
|
||||
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
||||
driver_parameter *settings, ppp_module_key_type type)
|
||||
{
|
||||
if(type != PPP_AUTHENTICATOR_KEY_TYPE)
|
||||
if (type != PPP_AUTHENTICATOR_KEY_TYPE)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
PAP *pap;
|
||||
bool success;
|
||||
if(subInterface) {
|
||||
if (subInterface) {
|
||||
pap = new PAP(*subInterface, settings);
|
||||
success = subInterface->AddProtocol(pap);
|
||||
} else {
|
||||
pap = new PAP(mainInterface, settings);
|
||||
success = mainInterface.AddProtocol(pap);
|
||||
}
|
||||
|
||||
|
||||
TRACE("PAP: add_to(): %s\n",
|
||||
success && pap && pap->InitCheck() == B_OK ? "OK" : "ERROR");
|
||||
|
||||
|
||||
return success && pap && pap->InitCheck() == B_OK;
|
||||
}
|
||||
|
||||
@@ -58,22 +57,28 @@ static ppp_module_info pap_module = {
|
||||
|
||||
_EXPORT
|
||||
status_t
|
||||
std_ops(int32 op, ...)
|
||||
std_ops(int32 op, ...)
|
||||
{
|
||||
switch(op) {
|
||||
switch (op) {
|
||||
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;
|
||||
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:
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
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, linlongzhou@163.com
|
||||
*/
|
||||
|
||||
|
||||
#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, linlongzhou@163.com
|
||||
*/
|
||||
|
||||
|
||||
#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, axeld@pinc-software.de
|
||||
* Lin Longzhou, linlongzhou@163.com
|
||||
*/
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <NetBufferUtilities.h>
|
||||
#include <net_buffer.h>
|
||||
|
||||
#include "DiscoveryPacket.h"
|
||||
|
||||
#include <core_funcs.h>
|
||||
|
||||
|
||||
DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID)
|
||||
: fCode(code),
|
||||
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
|
||||
uint8 *data = mtod(packet, uint8*);
|
||||
data += start;
|
||||
pppoe_header *header = (pppoe_header*) data;
|
||||
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK) {
|
||||
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;
|
||||
return;
|
||||
// there are no tags (or one corrupted tag)
|
||||
@@ -37,7 +46,7 @@ DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start)
|
||||
pppoe_tag *tag;
|
||||
|
||||
while(position <= length - 4) {
|
||||
tag = (pppoe_tag*) (header->data + position);
|
||||
tag = (pppoe_tag*) (header.data + position);
|
||||
position += ntohs(tag->length) + 4;
|
||||
|
||||
AddTag(ntohs(tag->type), tag->data, ntohs(tag->length));
|
||||
@@ -116,13 +125,21 @@ DiscoveryPacket::TagWithType(uint16 type) const
|
||||
}
|
||||
|
||||
|
||||
struct mbuf*
|
||||
DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
||||
net_buffer*
|
||||
DiscoveryPacket::ToNetBuffer(uint32 MTU)
|
||||
{
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
packet->m_data += reserve;
|
||||
|
||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||
net_buffer *packet = gBufferModule->create(256);
|
||||
if (packet == NULL) {
|
||||
dprintf("create buffer failure\n");
|
||||
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->type = PPPoE_TYPE;
|
||||
@@ -137,7 +154,7 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
||||
|
||||
// make sure we have enough space left
|
||||
if(MTU - length < tag->length) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -150,7 +167,11 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <TemplateList.h>
|
||||
|
||||
#define ETHER_HDR_LEN 14
|
||||
|
||||
enum PPPoE_TAG_TYPE {
|
||||
END_OF_LIST = 0x0000,
|
||||
@@ -37,13 +38,13 @@ typedef struct pppoe_tag {
|
||||
uint16 type;
|
||||
uint16 length;
|
||||
uint8 data[0];
|
||||
};
|
||||
} pppoe_tag;
|
||||
|
||||
|
||||
class DiscoveryPacket {
|
||||
public:
|
||||
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
|
||||
DiscoveryPacket(struct mbuf *packet, uint32 start = 0);
|
||||
DiscoveryPacket(net_buffer *packet, uint32 start = 0);
|
||||
~DiscoveryPacket();
|
||||
|
||||
status_t InitCheck() const
|
||||
@@ -66,8 +67,8 @@ class DiscoveryPacket {
|
||||
pppoe_tag *TagAt(int32 index) const;
|
||||
pppoe_tag *TagWithType(uint16 type) const;
|
||||
|
||||
struct mbuf *ToMbuf(uint32 MTU, uint32 reserve = ETHER_HDR_LEN);
|
||||
// the user is responsible for freeing the mbuf
|
||||
net_buffer *ToNetBuffer(uint32 MTU);
|
||||
// the user is responsible for freeing the net_buffer
|
||||
|
||||
private:
|
||||
uint8 fCode;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
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.
|
||||
}
|
||||
|
||||
# for kernel_cpp.h and BLocker
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
|
||||
{
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
}
|
||||
|
||||
|
||||
KernelAddon pppoe :
|
||||
pppoe.cpp
|
||||
PPPoEDevice.cpp
|
||||
@@ -32,5 +26,5 @@ LinkAgainst pppoe : libkernelppp.a ;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
||||
: /boot/home/config/add-ons/kernel/haiku/ppp
|
||||
: pppoe ;
|
||||
|
||||
@@ -8,10 +8,15 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#include <ethernet.h>
|
||||
#include <ether_driver.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
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 'PoEQ'
|
||||
@@ -60,14 +65,14 @@ typedef struct complete_pppoe_header {
|
||||
|
||||
|
||||
// defined in pppoe.cpp
|
||||
extern ifnet *FindPPPoEInterface(const char *name);
|
||||
extern net_device *FindPPPoEInterface(const char *name);
|
||||
extern uint32 NewHostUniq();
|
||||
extern void add_device(PPPoEDevice *device);
|
||||
extern void remove_device(PPPoEDevice *device);
|
||||
|
||||
#if DEBUG
|
||||
// defined in PPPoEDevice.cpp
|
||||
extern void dump_packet(struct mbuf *packet);
|
||||
extern void dump_packet(net_buffer *packet);
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
|
||||
@@ -3,41 +3,57 @@
|
||||
* 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 "DiscoveryPacket.h"
|
||||
|
||||
#include <core_funcs.h>
|
||||
#include <cstdlib>
|
||||
|
||||
// from libkernelppp
|
||||
#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
|
||||
static char sDigits[] = "0123456789ABCDEF";
|
||||
void
|
||||
dump_packet(struct mbuf *packet)
|
||||
dump_packet(net_buffer *packet)
|
||||
{
|
||||
if(!packet)
|
||||
if (!packet)
|
||||
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 bufferIndex = 0;
|
||||
|
||||
|
||||
TRACE("Dumping packet;len=%ld;pkthdr.len=%d\n", packet->m_len,
|
||||
packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : -1);
|
||||
|
||||
for(uint32 index = 0; index < packet->m_len; index++) {
|
||||
|
||||
for (uint32 index = 0; index < packet->m_len; index++) {
|
||||
buffer[bufferIndex++] = sDigits[data[index] >> 4];
|
||||
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;
|
||||
TRACE("%s\n", buffer);
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -54,30 +70,39 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
|
||||
{
|
||||
#if DEBUG
|
||||
TRACE("PPPoEDevice: Constructor\n");
|
||||
if(!settings || !settings->parameters)
|
||||
if (!settings || !settings->parameters)
|
||||
TRACE("PPPoEDevice::ctor: No settings!\n");
|
||||
#endif
|
||||
|
||||
|
||||
interface.SetPFCOptions(PPP_ALLOW_PFC);
|
||||
// we do not want to fail just because the other side requests PFC
|
||||
|
||||
|
||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||
|
||||
SetMTU(1494);
|
||||
// MTU size does not contain PPP header
|
||||
|
||||
|
||||
if (!settings)
|
||||
dprintf("%s::%s: settings is NULL\n", __FILE__, __func__);
|
||||
|
||||
// find ethernet device
|
||||
const char *interfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings);
|
||||
if(!interfaceName)
|
||||
return;
|
||||
|
||||
finterfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings);
|
||||
TRACE("%s::%s: finterfaceName is %s\n", __FILE__, __func__,
|
||||
finterfaceName ? finterfaceName : "NULL");
|
||||
|
||||
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);
|
||||
|
||||
fEthernetIfnet = FindPPPoEInterface(interfaceName);
|
||||
|
||||
TRACE("fServiceName is %s\n", fServiceName ? fServiceName : "NULL");
|
||||
|
||||
// fEthernetIfnet = FindPPPoEInterface(interfaceName);
|
||||
|
||||
#if DEBUG
|
||||
if(!fEthernetIfnet)
|
||||
if (!fEthernetIfnet)
|
||||
TRACE("PPPoEDevice::ctor: could not find ethernet interface\n");
|
||||
else
|
||||
TRACE("%s::%s: Find Ethernet device", __FILE__, __func__);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -85,8 +110,10 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
|
||||
status_t
|
||||
PPPoEDevice::InitCheck() const
|
||||
{
|
||||
return EthernetIfnet() && EthernetIfnet()->output
|
||||
&& KPPPDevice::InitCheck() == B_OK ? B_OK : B_ERROR;
|
||||
if (KPPPDevice::InitCheck() != B_OK)
|
||||
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()
|
||||
{
|
||||
TRACE("PPPoEDevice: Up()\n");
|
||||
|
||||
if(InitCheck() != B_OK)
|
||||
|
||||
if (InitCheck() != B_OK)
|
||||
return false;
|
||||
|
||||
if(IsUp())
|
||||
|
||||
if (IsUp())
|
||||
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);
|
||||
|
||||
|
||||
fState = INITIAL;
|
||||
// reset state
|
||||
|
||||
if(fAttempts > PPPoE_MAX_ATTEMPTS) {
|
||||
|
||||
if (fAttempts > PPPoE_MAX_ATTEMPTS) {
|
||||
fAttempts = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
++fAttempts;
|
||||
// reset connection settings
|
||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||
|
||||
|
||||
// create PADI
|
||||
DiscoveryPacket discovery(PADI);
|
||||
if(ServiceName())
|
||||
if (ServiceName())
|
||||
discovery.AddTag(SERVICE_NAME, ServiceName(), strlen(ServiceName()));
|
||||
else
|
||||
discovery.AddTag(SERVICE_NAME, NULL, 0);
|
||||
discovery.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
|
||||
discovery.AddTag(END_OF_LIST, NULL, 0);
|
||||
|
||||
|
||||
// set up PPP header
|
||||
struct mbuf *packet = discovery.ToMbuf(MTU());
|
||||
if(!packet)
|
||||
net_buffer *packet = discovery.ToNetBuffer(MTU());
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
// create destination
|
||||
struct ether_header *ethernetHeader;
|
||||
struct sockaddr destination;
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
destination.sa_family = AF_UNSPEC;
|
||||
// raw packet with ethernet header
|
||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||
|
||||
|
||||
// create ether header
|
||||
NetBufferPrepend<ether_header> ethernetHeader(packet);
|
||||
if (ethernetHeader.Status() != B_OK)
|
||||
return false;
|
||||
ether_header &header = ethernetHeader.Data();
|
||||
|
||||
memset(header.destination, 0xff, ETHER_ADDRESS_LENGTH);
|
||||
memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||
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)
|
||||
if(fAttempts > 0 && !UpStarted()) {
|
||||
if (fAttempts > 0 && !UpStarted()) {
|
||||
fAttempts = 0;
|
||||
remove_device(this);
|
||||
DownEvent();
|
||||
return true;
|
||||
// there was no error
|
||||
}
|
||||
|
||||
|
||||
fState = PADI_SENT;
|
||||
// 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;
|
||||
fAttempts = 0;
|
||||
ERROR("PPPoEDevice::Up(): EthernetIfnet()->output() failed!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
dprintf("PPPoEDevice::Up(): EthernetIfnet()->output() success!\n");
|
||||
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -168,36 +226,41 @@ bool
|
||||
PPPoEDevice::Down()
|
||||
{
|
||||
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);
|
||||
|
||||
if(InitCheck() != B_OK)
|
||||
|
||||
if (InitCheck() != B_OK)
|
||||
return false;
|
||||
|
||||
|
||||
fState = INITIAL;
|
||||
fAttempts = 0;
|
||||
fNextTimeout = 0;
|
||||
// disable timeouts
|
||||
|
||||
if(!IsUp()) {
|
||||
|
||||
if (!IsUp()) {
|
||||
DownEvent();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
DownStarted();
|
||||
// this tells StateMachine that DownEvent() does not mean we lost connection
|
||||
|
||||
|
||||
// create PADT
|
||||
DiscoveryPacket discovery(PADT, SessionID());
|
||||
discovery.AddTag(END_OF_LIST, NULL, 0);
|
||||
|
||||
struct mbuf *packet = discovery.ToMbuf(MTU());
|
||||
if(!packet) {
|
||||
ERROR("PPPoEDevice::Down(): ToMbuf() failed; MTU=%ld\n", MTU());
|
||||
|
||||
net_buffer *packet = discovery.ToNetBuffer(MTU());
|
||||
if (!packet) {
|
||||
ERROR("PPPoEDevice::Down(): ToNetBuffer() failed; MTU=%ld\n", MTU());
|
||||
DownEvent();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// create destination
|
||||
struct ether_header *ethernetHeader;
|
||||
struct sockaddr destination;
|
||||
@@ -205,15 +268,15 @@ PPPoEDevice::Down()
|
||||
destination.sa_family = AF_UNSPEC;
|
||||
// raw packet with ethernet header
|
||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||
|
||||
ethernetHeader->type = ETHER_TYPE_PPPOE_DISCOVERY;
|
||||
memcpy(ethernetHeader->destination, fPeer, sizeof(fPeer));
|
||||
|
||||
// reset connection settings
|
||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||
|
||||
EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL);
|
||||
|
||||
EthernetIfnet()->module->send_data(EthernetIfnet(), packet);
|
||||
DownEvent();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -242,220 +305,261 @@ PPPoEDevice::CountOutputBytes() const
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
TRACE("PPPoEDevice: Send()\n");
|
||||
|
||||
if(!packet)
|
||||
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
else if(InitCheck() != B_OK || protocolNumber != 0) {
|
||||
else if (InitCheck() != B_OK || protocolNumber != 0) {
|
||||
ERROR("PPPoEDevice::Send(): InitCheck() != B_OK!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if(!IsUp()) {
|
||||
|
||||
if (!IsUp()) {
|
||||
ERROR("PPPoEDevice::Send(): no connection!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
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
|
||||
M_PREPEND(packet, PPPoE_HEADER_SIZE);
|
||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||
header->version = PPPoE_VERSION;
|
||||
header->type = PPPoE_TYPE;
|
||||
header->code = 0x00;
|
||||
header->sessionID = SessionID();
|
||||
header->length = htons(length);
|
||||
|
||||
// create destination
|
||||
struct ether_header *ethernetHeader;
|
||||
struct sockaddr destination;
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
destination.sa_family = AF_UNSPEC;
|
||||
// raw packet with ethernet header
|
||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||
ethernetHeader->ether_type = ETHERTYPE_PPPOE;
|
||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||
|
||||
if(!packet || !mtod(packet, pppoe_header*))
|
||||
NetBufferPrepend<pppoe_header> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return B_ERROR;
|
||||
pppoe_header &header = bufferheader.Data();
|
||||
header.version = PPPoE_VERSION;
|
||||
header.type = PPPoE_TYPE;
|
||||
header.code = 0x00;
|
||||
header.sessionID = SessionID();
|
||||
header.length = htons(length);
|
||||
bufferheader.Sync();
|
||||
|
||||
// create ether header
|
||||
NetBufferPrepend<ether_header> ethernetHeader(packet);
|
||||
if (ethernetHeader.Status() != B_OK)
|
||||
return false;
|
||||
ether_header ðheader = ethernetHeader.Data();
|
||||
|
||||
memcpy(ethheader.destination, fPeer, ETHER_ADDRESS_LENGTH);
|
||||
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");
|
||||
|
||||
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");
|
||||
remove_device(this);
|
||||
DownEvent();
|
||||
// DownEvent() without DownStarted() indicates connection lost
|
||||
return PPP_NO_CONNECTION;
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
complete_pppoe_header *completeHeader = mtod(packet, complete_pppoe_header*);
|
||||
if(!completeHeader) {
|
||||
m_freem(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
uint8 ethernetSource[6];
|
||||
memcpy(ethernetSource, completeHeader->ethernetHeader.ether_shost, sizeof(fPeer));
|
||||
status_t result = B_OK;
|
||||
|
||||
if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOE) {
|
||||
m_adj(packet, ETHER_HDR_LEN);
|
||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||
|
||||
if(!IsUp() || header->version != PPPoE_VERSION || header->type != PPPoE_TYPE
|
||||
|| header->code != 0x0 || header->sessionID != SessionID()) {
|
||||
m_freem(packet);
|
||||
struct sockaddr_dl& source = *(struct sockaddr_dl*)packet->source;
|
||||
memcpy(ethernetSource, source.sdl_data, sizeof(fPeer));
|
||||
|
||||
int32 PPP_Packet_Type = B_NET_FRAME_TYPE(source.sdl_type,
|
||||
ntohs(source.sdl_e_type));
|
||||
// bufferheader.Remove();
|
||||
// bufferheader.Sync();
|
||||
|
||||
if (PPP_Packet_Type == B_NET_FRAME_TYPE_PPPOE) {
|
||||
TRACE("ETHER_TYPE_PPPOE\n");
|
||||
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK) {
|
||||
TRACE("creat NetBufferHeaderReader fail\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
m_adj(packet, PPPoE_HEADER_SIZE);
|
||||
pppoe_header &header = bufferheader.Data();
|
||||
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);
|
||||
} 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
|
||||
if(header->version != PPPoE_VERSION || header->type != PPPoE_TYPE) {
|
||||
m_freem(packet);
|
||||
if (header.version != PPPoE_VERSION || header.type != PPPoE_TYPE) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail version type wrong\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if(IsDown()) {
|
||||
m_freem(packet);
|
||||
|
||||
if (IsDown()) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail PPPoEDev IsDown\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
DiscoveryPacket discovery(packet);
|
||||
switch(discovery.Code()) {
|
||||
case PADO: {
|
||||
if(fState != PADI_SENT) {
|
||||
m_freem(packet);
|
||||
dprintf("processing PADO\n");
|
||||
if (fState != PADI_SENT) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive faile not PADI_Sent \n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool hasServiceName = false, hasACName = false;
|
||||
pppoe_tag *tag;
|
||||
DiscoveryPacket reply(PADR);
|
||||
for(int32 index = 0; index < discovery.CountTags(); index++) {
|
||||
for (int32 index = 0; index < discovery.CountTags(); index++) {
|
||||
tag = discovery.TagAt(index);
|
||||
if(!tag)
|
||||
if (!tag)
|
||||
continue;
|
||||
|
||||
switch(tag->type) {
|
||||
|
||||
switch (tag->type) {
|
||||
case SERVICE_NAME:
|
||||
if(!hasServiceName && (!ServiceName()
|
||||
|| (strlen(ServiceName()) == tag->length)
|
||||
if (!hasServiceName && (!ServiceName()
|
||||
|| ((strlen(ServiceName()) == tag->length)
|
||||
&& !memcmp(tag->data, ServiceName(),
|
||||
tag->length))) {
|
||||
tag->length)))) {
|
||||
hasServiceName = true;
|
||||
reply.AddTag(tag->type, tag->data, tag->length);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case AC_NAME:
|
||||
if(!hasACName && (!ACName()
|
||||
|| (strlen(ACName()) == tag->length)
|
||||
if (!hasACName && (!ACName()
|
||||
|| ((strlen(ACName()) == tag->length)
|
||||
&& !memcmp(tag->data, ACName(),
|
||||
tag->length))) {
|
||||
tag->length)))) {
|
||||
hasACName = true;
|
||||
reply.AddTag(tag->type, tag->data, tag->length);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case AC_COOKIE:
|
||||
case RELAY_SESSION_ID:
|
||||
reply.AddTag(tag->type, tag->data, tag->length);
|
||||
break;
|
||||
|
||||
|
||||
case SERVICE_NAME_ERROR:
|
||||
case AC_SYSTEM_ERROR:
|
||||
case GENERIC_ERROR:
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::generic error faile\n");
|
||||
return B_ERROR;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if(!hasServiceName) {
|
||||
m_freem(packet);
|
||||
|
||||
if (!hasServiceName) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive faile no svc name\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
dprintf("reply.AddTag\n");
|
||||
reply.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
|
||||
reply.AddTag(END_OF_LIST, NULL, 0);
|
||||
struct mbuf *replyPacket = reply.ToMbuf(MTU());
|
||||
if(!replyPacket) {
|
||||
m_freem(packet);
|
||||
net_buffer *replyPacket = reply.ToNetBuffer(MTU());
|
||||
if (!replyPacket) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail no reply pack\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
memcpy(fPeer, ethernetSource, sizeof(fPeer));
|
||||
|
||||
// create destination
|
||||
struct ether_header *ethernetHeader;
|
||||
struct sockaddr destination;
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
destination.sa_family = AF_UNSPEC;
|
||||
// raw packet with ethernet header
|
||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||
|
||||
|
||||
memcpy(fPeer, ethernetSource, ETHER_ADDRESS_LENGTH);
|
||||
|
||||
// create ether header
|
||||
NetBufferPrepend<ether_header> ethernetHeader(replyPacket);
|
||||
if (ethernetHeader.Status() != B_OK)
|
||||
return false;
|
||||
ether_header &header = ethernetHeader.Data();
|
||||
|
||||
memcpy(header.destination, fPeer, ETHER_ADDRESS_LENGTH);
|
||||
memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||
header.type=htons(ETHER_TYPE_PPPOE_DISCOVERY);
|
||||
ethernetHeader.Sync();
|
||||
// raw packet with ethernet header
|
||||
|
||||
fState = PADR_SENT;
|
||||
|
||||
if(EthernetIfnet()->output(EthernetIfnet(), replyPacket, &destination,
|
||||
NULL) != B_OK) {
|
||||
m_freem(packet);
|
||||
|
||||
if (EthernetIfnet()->module->send_data(EthernetIfnet(), replyPacket) != B_OK) {
|
||||
gBufferModule->free(replyPacket);
|
||||
dprintf("PPPoEDevice::Receive fail send PADR\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
||||
} break;
|
||||
|
||||
}
|
||||
break;
|
||||
case PADS:
|
||||
if(fState != PADR_SENT
|
||||
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
|
||||
m_freem(packet);
|
||||
dprintf("procesing PADS\n");
|
||||
if (fState != PADR_SENT
|
||||
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive PADS but no PADR sent\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fSessionID = header->sessionID;
|
||||
|
||||
fSessionID = header.sessionID;
|
||||
fState = OPENED;
|
||||
fNextTimeout = 0;
|
||||
UpEvent();
|
||||
break;
|
||||
|
||||
|
||||
case PADT:
|
||||
if(!IsUp()
|
||||
dprintf("procesing PADT\n");
|
||||
if (!IsUp()
|
||||
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))
|
||||
|| header->sessionID != SessionID()) {
|
||||
m_freem(packet);
|
||||
|| header.sessionID != SessionID()) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail not up yet\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
fState = INITIAL;
|
||||
fAttempts = 0;
|
||||
fSessionID = 0;
|
||||
@@ -463,16 +567,17 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
remove_device(this);
|
||||
DownEvent();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
m_freem(packet);
|
||||
dprintf("PPPoEDevice::Receive fail unknown pppoed code\n");
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
} else
|
||||
result = B_ERROR;
|
||||
|
||||
m_freem(packet);
|
||||
return result;
|
||||
}
|
||||
|
||||
dprintf("PPPoEDevice::Receive PADX fine!\n");
|
||||
// gBufferModule->free(packet);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -480,13 +585,12 @@ void
|
||||
PPPoEDevice::Pulse()
|
||||
{
|
||||
// We use Pulse() for timeout of connection establishment.
|
||||
|
||||
if(fNextTimeout == 0 || IsUp() || IsDown())
|
||||
if (fNextTimeout == 0 || IsUp() || IsDown())
|
||||
return;
|
||||
|
||||
|
||||
// check if timed out
|
||||
if(system_time() >= fNextTimeout) {
|
||||
if(!Up())
|
||||
if (system_time() >= fNextTimeout) {
|
||||
if (!Up())
|
||||
UpFailedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
#include <KPPPDevice.h>
|
||||
|
||||
#include <net/if_types.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
|
||||
enum pppoe_state {
|
||||
INITIAL,
|
||||
@@ -25,7 +28,7 @@ class PPPoEDevice : public KPPPDevice {
|
||||
public:
|
||||
PPPoEDevice(KPPPInterface& interface, driver_parameter *settings);
|
||||
|
||||
ifnet *EthernetIfnet() const
|
||||
net_device *EthernetIfnet() const
|
||||
{ return fEthernetIfnet; }
|
||||
|
||||
const uint8 *Peer() const
|
||||
@@ -50,17 +53,19 @@ class PPPoEDevice : public KPPPDevice {
|
||||
|
||||
virtual uint32 CountOutputBytes() const;
|
||||
|
||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber = 0);
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber = 0);
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber = 0);
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber = 0);
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
private:
|
||||
ifnet *fEthernetIfnet;
|
||||
net_device *fEthernetIfnet;
|
||||
uint8 fPeer[6];
|
||||
uint8 fEtherAddr[6];
|
||||
uint16 fSessionID;
|
||||
uint32 fHostUniq;
|
||||
const char *fACName, *fServiceName;
|
||||
const char *finterfaceName;
|
||||
|
||||
uint32 fAttempts;
|
||||
bigtime_t fNextTimeout;
|
||||
|
||||
@@ -5,34 +5,46 @@
|
||||
|
||||
#include <KernelExport.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 <KPPPModule.h>
|
||||
#include <KPPPUtils.h>
|
||||
#include <LockerHelper.h>
|
||||
|
||||
#include "PPPoEDevice.h"
|
||||
#include "DiscoveryPacket.h"
|
||||
|
||||
|
||||
typedef struct pppoe_query {
|
||||
ifnet *ethernetIfnet;
|
||||
net_device *ethernetIfnet;
|
||||
uint32 hostUniq;
|
||||
thread_id receiver;
|
||||
} 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;
|
||||
status_t std_ops(int32 op, ...);
|
||||
|
||||
static BLocker sLock("PPPoEList");
|
||||
// static mutex sLock("PPPoEList");
|
||||
|
||||
static TemplateList<PPPoEDevice*> *sDevices;
|
||||
static TemplateList<pppoe_query*> *sQueries;
|
||||
|
||||
@@ -44,51 +56,75 @@ SendQueryPacket(pppoe_query *query, DiscoveryPacket& discovery)
|
||||
char data[PPPoE_QUERY_REPORT_SIZE];
|
||||
uint32 position = sizeof(uint32);
|
||||
pppoe_tag *acName = discovery.TagWithType(AC_NAME);
|
||||
|
||||
if(acName) {
|
||||
if(acName->length >= PPPoE_QUERY_REPORT_SIZE)
|
||||
|
||||
if (acName) {
|
||||
if (acName->length >= PPPoE_QUERY_REPORT_SIZE)
|
||||
return;
|
||||
|
||||
|
||||
memcpy(data + position, acName->data, acName->length);
|
||||
position += acName->length;
|
||||
}
|
||||
|
||||
|
||||
data[position++] = 0;
|
||||
|
||||
|
||||
pppoe_tag *tag;
|
||||
for(int32 index = 0; index < discovery.CountTags(); index++) {
|
||||
for (int32 index = 0; index < discovery.CountTags(); index++) {
|
||||
tag = discovery.TagAt(index);
|
||||
if(tag && tag->type == SERVICE_NAME) {
|
||||
if(position + tag->length >= PPPoE_QUERY_REPORT_SIZE)
|
||||
if (tag && tag->type == SERVICE_NAME) {
|
||||
if (position + tag->length >= PPPoE_QUERY_REPORT_SIZE)
|
||||
return;
|
||||
|
||||
|
||||
memcpy(data + position, tag->data, tag->length);
|
||||
position += tag->length;
|
||||
data[position++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memcpy(data, &position, sizeof(uint32));
|
||||
// add the total length
|
||||
|
||||
|
||||
send_data_with_timeout(query->receiver, PPPoE_QUERY_REPORT, data,
|
||||
PPPoE_QUERY_REPORT_SIZE, 700000);
|
||||
}
|
||||
|
||||
|
||||
ifnet*
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -104,9 +140,9 @@ void
|
||||
add_device(PPPoEDevice *device)
|
||||
{
|
||||
TRACE("PPPoE: add_device()\n");
|
||||
|
||||
LockerHelper locker(sLock);
|
||||
if(!sDevices->HasItem(device))
|
||||
|
||||
// MutexLocker locker(sLock);
|
||||
if (!sDevices->HasItem(device))
|
||||
sDevices->AddItem(device);
|
||||
}
|
||||
|
||||
@@ -115,85 +151,125 @@ void
|
||||
remove_device(PPPoEDevice *device)
|
||||
{
|
||||
TRACE("PPPoE: remove_device()\n");
|
||||
|
||||
LockerHelper locker(sLock);
|
||||
|
||||
// MutexLocker locker(sLock);
|
||||
sDevices->RemoveItem(device);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
pppoe_input(struct mbuf *packet)
|
||||
status_t
|
||||
pppoe_input(void *cookie, net_device *_device, net_buffer *packet)
|
||||
{
|
||||
if(!packet)
|
||||
return;
|
||||
|
||||
ifnet *sourceIfnet = packet->m_pkthdr.rcvif;
|
||||
complete_pppoe_header *header = mtod(packet, complete_pppoe_header*);
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
|
||||
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||
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;
|
||||
pppoe_query *query;
|
||||
|
||||
LockerHelper locker(sLock);
|
||||
|
||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC
|
||||
&& header->pppoeHeader.length <= PPPoE_QUERY_REPORT_SIZE) {
|
||||
for(int32 index = 0; index < sDevices->CountItems(); index++) {
|
||||
|
||||
sockaddr_dl& linkAddress = *(sockaddr_dl*)packet->source;
|
||||
int32 specificType = B_NET_FRAME_TYPE(linkAddress.sdl_type,
|
||||
ntohs(linkAddress.sdl_e_type));
|
||||
|
||||
// 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);
|
||||
|
||||
if(query && query->ethernetIfnet == sourceIfnet) {
|
||||
if(header->pppoeHeader.code == PADO) {
|
||||
|
||||
if (query) {// && query->ethernetIfnet == sourceIfnet) {
|
||||
if (header.code == PADO) {
|
||||
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||
if(discovery.InitCheck() != B_OK) {
|
||||
if (discovery.InitCheck() != B_OK) {
|
||||
ERROR("PPPoE: received corrupted discovery packet!\n");
|
||||
m_freem(packet);
|
||||
return;
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
pppoe_tag *hostTag = discovery.TagWithType(HOST_UNIQ);
|
||||
if(hostTag && hostTag->length == 4
|
||||
if (hostTag && hostTag->length == 4
|
||||
&& *((uint32*)hostTag->data) == query->hostUniq) {
|
||||
SendQueryPacket(query, discovery);
|
||||
m_freem(packet);
|
||||
return;
|
||||
// gBufferModule->free(packet);
|
||||
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);
|
||||
|
||||
if(device && device->EthernetIfnet() == sourceIfnet) {
|
||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE
|
||||
&& header->pppoeHeader.sessionID == device->SessionID()) {
|
||||
|
||||
TRACE("device->SessionID() %d, header.sessionID: %d\n", device->SessionID(),
|
||||
header.sessionID);
|
||||
|
||||
if (device) { // && device->EthernetIfnet() == sourceIfnet) {
|
||||
if (specificType == B_NET_FRAME_TYPE_PPPOE
|
||||
&& header.sessionID == device->SessionID()) {
|
||||
TRACE("PPPoE: session packet\n");
|
||||
device->Receive(packet);
|
||||
return;
|
||||
} else if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC
|
||||
&& header->pppoeHeader.code != PADI
|
||||
&& header->pppoeHeader.code != PADR
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
|
||||
&& header.code != PADI
|
||||
&& header.code != PADR
|
||||
&& !device->IsDown()) {
|
||||
TRACE("PPPoE: discovery packet\n");
|
||||
|
||||
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||
if(discovery.InitCheck() != B_OK) {
|
||||
if (discovery.InitCheck() != B_OK) {
|
||||
ERROR("PPPoE: received corrupted discovery packet!\n");
|
||||
m_freem(packet);
|
||||
return;
|
||||
gBufferModule->free(packet);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ);
|
||||
if(header->pppoeHeader.code == PADT || (tag && tag->length == 4
|
||||
&& *((uint32*)tag->data) == device->HostUniq())) {
|
||||
if (header.code == PADT || (tag && tag->length == 4
|
||||
&& *((uint32*)tag->data) == device->HostUniq())) {
|
||||
device->Receive(packet);
|
||||
return;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ERROR("PPPoE: No device found for packet from: %s\n", sourceIfnet->if_name);
|
||||
m_freem(packet);
|
||||
|
||||
ERROR("PPPoE: No device found for packet from: %s\n", "ethernet");
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,22 +278,22 @@ bool
|
||||
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
||||
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;
|
||||
|
||||
|
||||
PPPoEDevice *device;
|
||||
bool success;
|
||||
if(subInterface) {
|
||||
if (subInterface) {
|
||||
device = new PPPoEDevice(*subInterface, settings);
|
||||
success = subInterface->SetDevice(device);
|
||||
} else {
|
||||
device = new PPPoEDevice(mainInterface, settings);
|
||||
success = mainInterface.SetDevice(device);
|
||||
}
|
||||
|
||||
|
||||
TRACE("PPPoE: add_to(): %s\n",
|
||||
success && device && device->InitCheck() == B_OK ? "OK" : "ERROR");
|
||||
|
||||
|
||||
return success && device && device->InitCheck() == B_OK;
|
||||
}
|
||||
|
||||
@@ -226,59 +302,62 @@ static
|
||||
status_t
|
||||
control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
switch(op) {
|
||||
switch (op) {
|
||||
case PPPoE_GET_INTERFACES: {
|
||||
int32 position = 0, count = 0;
|
||||
char *names = (char*) data;
|
||||
|
||||
ifnet *current = get_interfaces();
|
||||
for(; current; current = current->if_next) {
|
||||
if(current->if_type == IFT_ETHER && current->if_name) {
|
||||
if(position + strlen(current->if_name) + 1 > length)
|
||||
|
||||
net_device *current = NULL; // get_interfaces();
|
||||
for (; current; current = NULL) {
|
||||
if (current->type == IFT_ETHER && current->name) {
|
||||
if (position + strlen(current->name) + 1 > length)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
strcpy(names + position, current->if_name);
|
||||
position += strlen(current->if_name);
|
||||
|
||||
strcpy(names + position, current->name);
|
||||
position += strlen(current->name);
|
||||
names[position++] = 0;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
case PPPoE_QUERY_SERVICES: {
|
||||
// XXX: as all modules are loaded on-demand we must wait for the results
|
||||
|
||||
if(!data || length != sizeof(pppoe_query_request))
|
||||
|
||||
if (!data || length != sizeof(pppoe_query_request))
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
pppoe_query_request *request = (pppoe_query_request*) data;
|
||||
|
||||
|
||||
pppoe_query query;
|
||||
query.ethernetIfnet = FindPPPoEInterface(request->interfaceName);
|
||||
if(!query.ethernetIfnet)
|
||||
if (!query.ethernetIfnet)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
|
||||
query.hostUniq = NewHostUniq();
|
||||
query.receiver = request->receiver;
|
||||
|
||||
sLock.Lock();
|
||||
sQueries->AddItem(&query);
|
||||
sLock.Unlock();
|
||||
|
||||
|
||||
{
|
||||
// MutexLocker tlocker(sLock);
|
||||
TRACE("add query\n");
|
||||
sQueries->AddItem(&query);
|
||||
}
|
||||
|
||||
snooze(2000000);
|
||||
// wait two seconds for results
|
||||
|
||||
sLock.Lock();
|
||||
sQueries->RemoveItem(&query);
|
||||
sLock.Unlock();
|
||||
{
|
||||
// MutexLocker tlocker(sLock);
|
||||
TRACE("remove query\n");
|
||||
sQueries->RemoveItem(&query);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -296,40 +375,48 @@ static ppp_module_info pppoe_module = {
|
||||
|
||||
_EXPORT
|
||||
status_t
|
||||
std_ops(int32 op, ...)
|
||||
std_ops(int32 op, ...)
|
||||
{
|
||||
switch(op) {
|
||||
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;
|
||||
|
||||
if(get_module(NET_ETHERNET_MODULE_NAME,
|
||||
(module_info**) &sEthernet) != B_OK) {
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
|
||||
if (get_module(NET_DATALINK_MODULE_NAME,
|
||||
(module_info **)&sDatalinkModule) != B_OK) {
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
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
|
||||
sDevices = new TemplateList<PPPoEDevice*>;
|
||||
sQueries = new TemplateList<pppoe_query*>;
|
||||
sEthernet->set_pppoe_receiver(pppoe_input);
|
||||
|
||||
|
||||
TRACE("PPPoE: Registered PPPoE receiver.\n");
|
||||
return B_OK;
|
||||
|
||||
return B_OK;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
delete sQueries;
|
||||
delete sDevices;
|
||||
sEthernet->unset_pppoe_receiver();
|
||||
TRACE("PPPoE: Unregistered PPPoE receiver.\n");
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
put_module(NET_ETHERNET_MODULE_NAME);
|
||||
break;
|
||||
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
put_module(NET_DATALINK_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ if $(TARGET_PLATFORM) != haiku {
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
UsePrivateHeaders libroot net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
@@ -37,7 +40,6 @@ KernelStaticLibrary libkernelppp.a :
|
||||
KPPPReportManager.cpp
|
||||
KPPPStateMachine.cpp
|
||||
KPPPUtils.cpp
|
||||
Locker.cpp
|
||||
settings_tools.cpp
|
||||
|
||||
# integrated modules
|
||||
@@ -49,7 +51,5 @@ KernelStaticLibrary libkernelppp.a :
|
||||
|
||||
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||
= [ 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 ]
|
||||
= [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
|
||||
|
||||
@@ -5,18 +5,20 @@
|
||||
|
||||
/*! \class KPPPConfigurePacket
|
||||
\brief Helper class for LCP configure packets.
|
||||
|
||||
|
||||
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 <KPPPInterface.h>
|
||||
|
||||
#include <core_funcs.h>
|
||||
|
||||
|
||||
/*! \brief Constructor.
|
||||
|
||||
|
||||
\param code The code value (e.g.: PPP_CONFIGURE_REQUEST) of this packet.
|
||||
*/
|
||||
KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
|
||||
@@ -27,30 +29,33 @@ KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
|
||||
|
||||
|
||||
//! Decodes a packet and adds its items to this object.
|
||||
KPPPConfigurePacket::KPPPConfigurePacket(struct mbuf *packet)
|
||||
KPPPConfigurePacket::KPPPConfigurePacket(net_buffer *packet)
|
||||
{
|
||||
// decode packet
|
||||
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
||||
|
||||
SetID(header->id);
|
||||
if (!SetCode(header->code))
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferhead(packet);
|
||||
if (bufferhead.Status() != B_OK)
|
||||
return;
|
||||
|
||||
uint16 length = ntohs(header->length);
|
||||
|
||||
if (length < 6 || length > packet->m_len)
|
||||
ppp_lcp_packet &header = bufferhead.Data();
|
||||
|
||||
SetID(header.id);
|
||||
if (!SetCode(header.code))
|
||||
return;
|
||||
|
||||
uint16 length = ntohs(header.length);
|
||||
|
||||
if (length < 6 || length > packet->size)
|
||||
return;
|
||||
// there are no items (or one corrupted item)
|
||||
|
||||
|
||||
int32 position = 0;
|
||||
ppp_configure_item *item;
|
||||
|
||||
|
||||
while (position < length - 4) {
|
||||
item = (ppp_configure_item*) (header->data + position);
|
||||
item = (ppp_configure_item*) (header.data + position);
|
||||
if (item->length < 2)
|
||||
return;
|
||||
// found a corrupted item
|
||||
|
||||
|
||||
position += item->length;
|
||||
AddItem(item);
|
||||
}
|
||||
@@ -72,23 +77,23 @@ KPPPConfigurePacket::SetCode(uint8 code)
|
||||
// only configure codes are allowed!
|
||||
if (code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT)
|
||||
return false;
|
||||
|
||||
|
||||
fCode = code;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*! \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
|
||||
length field is incorrect you will get bad results.
|
||||
|
||||
|
||||
\param item The item.
|
||||
\param index Item's index. Adds after the last item if not specified or negative.
|
||||
|
||||
|
||||
\return \c true if successful, \c false otherwise.
|
||||
|
||||
|
||||
\sa ppp_configure_item
|
||||
*/
|
||||
bool
|
||||
@@ -96,10 +101,10 @@ KPPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index)
|
||||
{
|
||||
if (!item || item->length < 2)
|
||||
return false;
|
||||
|
||||
|
||||
ppp_configure_item *add = (ppp_configure_item*) malloc(item->length);
|
||||
memcpy(add, item, item->length);
|
||||
|
||||
|
||||
bool status;
|
||||
if (index < 0)
|
||||
status = fItems.AddItem(add);
|
||||
@@ -109,7 +114,7 @@ KPPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index)
|
||||
free(add);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -120,10 +125,10 @@ KPPPConfigurePacket::RemoveItem(ppp_configure_item *item)
|
||||
{
|
||||
if (!fItems.HasItem(item))
|
||||
return false;
|
||||
|
||||
|
||||
fItems.RemoveItem(item);
|
||||
free(item);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -133,10 +138,10 @@ ppp_configure_item*
|
||||
KPPPConfigurePacket::ItemAt(int32 index) const
|
||||
{
|
||||
ppp_configure_item *item = fItems.ItemAt(index);
|
||||
|
||||
|
||||
if (item == fItems.GetDefaultItem())
|
||||
return NULL;
|
||||
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -146,56 +151,71 @@ ppp_configure_item*
|
||||
KPPPConfigurePacket::ItemWithType(uint8 type) const
|
||||
{
|
||||
ppp_configure_item *item;
|
||||
|
||||
|
||||
for (int32 index = 0; index < CountItems(); index++) {
|
||||
item = ItemAt(index);
|
||||
if (item && item->type == type)
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
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()!
|
||||
|
||||
|
||||
\param MRU The interface's maximum receive unit (MRU).
|
||||
\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*
|
||||
KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve)
|
||||
net_buffer*
|
||||
KPPPConfigurePacket::ToNetBuffer(uint32 MRU)
|
||||
{
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
packet->m_data += reserve;
|
||||
|
||||
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
||||
|
||||
net_buffer *buffer = gBufferModule->create(256);
|
||||
if (buffer == NULL) {
|
||||
TRACE("%s::%s: gBufferModule->create fail\n", __FILE__, __func__);
|
||||
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->id = ID();
|
||||
|
||||
|
||||
uint16 length = 0;
|
||||
ppp_configure_item *item;
|
||||
|
||||
|
||||
for (int32 index = 0; index < CountItems(); index++) {
|
||||
item = ItemAt(index);
|
||||
|
||||
|
||||
// make sure we have enough space left
|
||||
if (MRU - length < item->length) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
memcpy(header->data + length, item, item->length);
|
||||
length += item->length;
|
||||
}
|
||||
|
||||
|
||||
length += 4;
|
||||
header->length = htons(length);
|
||||
packet->m_pkthdr.len = packet->m_len = length;
|
||||
|
||||
return packet;
|
||||
|
||||
status = gBufferModule->trim(buffer, length);
|
||||
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
|
||||
\brief Represents a device at the lowest level of the communcation stack.
|
||||
|
||||
|
||||
A device may be, for example: Modem, PPPoE, PPTP. \n
|
||||
It encapsulates the packet and sends it over a line to the other end.
|
||||
The device is the first layer that receives a packet.
|
||||
@@ -14,13 +14,12 @@
|
||||
#include <KPPPDevice.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <core_funcs.h>
|
||||
|
||||
#include <PPPControl.h>
|
||||
|
||||
|
||||
/*! \brief Initializes the device.
|
||||
|
||||
|
||||
\param name The device's type name (e.g.: PPPoE).
|
||||
\param overhead Length of the header that is prepended to each packet.
|
||||
\param interface Owning interface.
|
||||
@@ -46,12 +45,13 @@ KPPPDevice::~KPPPDevice()
|
||||
|
||||
|
||||
/*! \brief Allows private extensions.
|
||||
|
||||
|
||||
If you override this method you must call the parent's method for unknown ops.
|
||||
*/
|
||||
status_t
|
||||
KPPPDevice::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
dprintf("KPPPDevice::Control\n");
|
||||
switch (op) {
|
||||
case PPPC_GET_DEVICE_INFO:
|
||||
{
|
||||
@@ -89,7 +89,7 @@ KPPPDevice::IsAllowedToSend() const
|
||||
|
||||
//! This method is never used.
|
||||
status_t
|
||||
KPPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
KPPPDevice::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
// let the interface handle the packet
|
||||
if (protocolNumber == 0)
|
||||
@@ -100,10 +100,10 @@ KPPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
|
||||
|
||||
/*! \brief Report that device is going up.
|
||||
|
||||
|
||||
Called by Up(). \n
|
||||
From now on, the connection attempt can may be aborted by calling Down().
|
||||
|
||||
|
||||
\return
|
||||
- \c true: You are allowed to connect.
|
||||
- \c false: You should abort immediately. Down() will \e not be called!
|
||||
@@ -112,15 +112,15 @@ bool
|
||||
KPPPDevice::UpStarted()
|
||||
{
|
||||
fConnectionPhase = PPP_ESTABLISHMENT_PHASE;
|
||||
|
||||
|
||||
return Interface().StateMachine().TLSNotify();
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Report that device is going down.
|
||||
|
||||
|
||||
Called by Down().
|
||||
|
||||
|
||||
\return
|
||||
- \c true: You are allowed to disconnect.
|
||||
- \c false: You must not disconnect!
|
||||
@@ -129,7 +129,7 @@ bool
|
||||
KPPPDevice::DownStarted()
|
||||
{
|
||||
fConnectionPhase = PPP_TERMINATION_PHASE;
|
||||
|
||||
|
||||
return Interface().StateMachine().TLFNotify();
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ void
|
||||
KPPPDevice::UpFailedEvent()
|
||||
{
|
||||
fConnectionPhase = PPP_DOWN_PHASE;
|
||||
|
||||
|
||||
Interface().StateMachine().UpFailedEvent();
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ void
|
||||
KPPPDevice::UpEvent()
|
||||
{
|
||||
fConnectionPhase = PPP_ESTABLISHED_PHASE;
|
||||
|
||||
|
||||
Interface().StateMachine().UpEvent();
|
||||
}
|
||||
|
||||
@@ -159,6 +159,6 @@ void
|
||||
KPPPDevice::DownEvent()
|
||||
{
|
||||
fConnectionPhase = PPP_DOWN_PHASE;
|
||||
|
||||
|
||||
Interface().StateMachine().DownEvent();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
|
||||
/*! \class KPPPLCP
|
||||
\brief The LCP protocol.
|
||||
|
||||
|
||||
Every PPP interface \e must have an LCP protocol. It is used for establishing
|
||||
and terminating connections. \n
|
||||
When establishing a connecition the LCP protocol determines connection-specific
|
||||
@@ -20,9 +20,12 @@
|
||||
#include <KPPPOptionHandler.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <core_funcs.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
extern net_buffer_module_info *gBufferModule;
|
||||
|
||||
|
||||
//! Creates a new LCP protocol for the given interface.
|
||||
KPPPLCP::KPPPLCP(KPPPInterface& interface)
|
||||
@@ -48,7 +51,7 @@ KPPPLCP::~KPPPLCP()
|
||||
|
||||
|
||||
/*! \brief Adds a new option handler.
|
||||
|
||||
|
||||
NOTE: You can only add option handlers in \c PPP_DOWN_PHASE. \n
|
||||
There may only be one handler per option type!
|
||||
*/
|
||||
@@ -57,19 +60,19 @@ KPPPLCP::AddOptionHandler(KPPPOptionHandler *optionHandler)
|
||||
{
|
||||
if (!optionHandler || &optionHandler->Interface() != &Interface())
|
||||
return false;
|
||||
|
||||
|
||||
if (Interface().Phase() != PPP_DOWN_PHASE
|
||||
|| OptionHandlerFor(optionHandler->Type()))
|
||||
return false;
|
||||
// a running connection may not change and there may only be
|
||||
// one handler per option type
|
||||
|
||||
|
||||
return fOptionHandlers.AddItem(optionHandler);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Removes an option handler, but does not delete it.
|
||||
|
||||
|
||||
NOTE: You can only remove option handlers in \c PPP_DOWN_PHASE.
|
||||
*/
|
||||
bool
|
||||
@@ -78,7 +81,7 @@ KPPPLCP::RemoveOptionHandler(KPPPOptionHandler *optionHandler)
|
||||
if (Interface().Phase() != PPP_DOWN_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
|
||||
return fOptionHandlers.RemoveItem(optionHandler);
|
||||
}
|
||||
|
||||
@@ -87,11 +90,12 @@ KPPPLCP::RemoveOptionHandler(KPPPOptionHandler *optionHandler)
|
||||
KPPPOptionHandler*
|
||||
KPPPLCP::OptionHandlerAt(int32 index) const
|
||||
{
|
||||
dprintf("total optionhandler count %ld\n", CountOptionHandlers());
|
||||
KPPPOptionHandler *optionHandler = fOptionHandlers.ItemAt(index);
|
||||
|
||||
|
||||
if (optionHandler == fOptionHandlers.GetDefaultItem())
|
||||
return NULL;
|
||||
|
||||
|
||||
return optionHandler;
|
||||
}
|
||||
|
||||
@@ -103,14 +107,14 @@ KPPPLCP::OptionHandlerFor(uint8 type, int32 *start) const
|
||||
// The iteration style in this method is strange C/C++.
|
||||
// Explanation: I use this style because it makes extending all XXXFor
|
||||
// methods simpler as that they look very similar, now.
|
||||
|
||||
|
||||
int32 index = start ? *start : 0;
|
||||
|
||||
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
KPPPOptionHandler *current = OptionHandlerAt(index);
|
||||
|
||||
|
||||
for (; current; current = OptionHandlerAt(++index)) {
|
||||
if (current->Type() == type) {
|
||||
if (start)
|
||||
@@ -118,13 +122,13 @@ KPPPLCP::OptionHandlerFor(uint8 type, int32 *start) const
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Adds a new LCP extension.
|
||||
|
||||
|
||||
NOTE: You can only add LCP extensions in \c PPP_DOWN_PHASE.
|
||||
*/
|
||||
bool
|
||||
@@ -132,17 +136,17 @@ KPPPLCP::AddLCPExtension(KPPPLCPExtension *lcpExtension)
|
||||
{
|
||||
if (!lcpExtension || &lcpExtension->Interface() != &Interface())
|
||||
return false;
|
||||
|
||||
|
||||
if (Interface().Phase() != PPP_DOWN_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
|
||||
return fLCPExtensions.AddItem(lcpExtension);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Removes an LCP extension, but does not delete it.
|
||||
|
||||
|
||||
NOTE: You can only remove LCP extensions in \c PPP_DOWN_PHASE.
|
||||
*/
|
||||
bool
|
||||
@@ -151,7 +155,7 @@ KPPPLCP::RemoveLCPExtension(KPPPLCPExtension *lcpExtension)
|
||||
if (Interface().Phase() != PPP_DOWN_PHASE)
|
||||
return false;
|
||||
// a running connection may not change
|
||||
|
||||
|
||||
return fLCPExtensions.RemoveItem(lcpExtension);
|
||||
}
|
||||
|
||||
@@ -160,11 +164,12 @@ KPPPLCP::RemoveLCPExtension(KPPPLCPExtension *lcpExtension)
|
||||
KPPPLCPExtension*
|
||||
KPPPLCP::LCPExtensionAt(int32 index) const
|
||||
{
|
||||
dprintf("LCPExtension count %ld\n", CountLCPExtensions());
|
||||
KPPPLCPExtension *lcpExtension = fLCPExtensions.ItemAt(index);
|
||||
|
||||
|
||||
if (lcpExtension == fLCPExtensions.GetDefaultItem())
|
||||
return NULL;
|
||||
|
||||
|
||||
return lcpExtension;
|
||||
}
|
||||
|
||||
@@ -176,14 +181,14 @@ KPPPLCP::LCPExtensionFor(uint8 code, int32 *start) const
|
||||
// The iteration style in this method is strange C/C++.
|
||||
// Explanation: I use this style because it makes extending all XXXFor
|
||||
// methods simpler as that they look very similar, now.
|
||||
|
||||
|
||||
int32 index = start ? *start : 0;
|
||||
|
||||
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
KPPPLCPExtension *current = LCPExtensionAt(index);
|
||||
|
||||
|
||||
for (; current; current = LCPExtensionAt(++index)) {
|
||||
if (current->Code() == code) {
|
||||
if (start)
|
||||
@@ -191,27 +196,11 @@ KPPPLCP::LCPExtensionFor(uint8 code, int32 *start) const
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
bool
|
||||
KPPPLCP::Up()
|
||||
@@ -230,7 +219,7 @@ KPPPLCP::Down()
|
||||
|
||||
//! Sends a packet to the target (if there is one) or to the interface.
|
||||
status_t
|
||||
KPPPLCP::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
KPPPLCP::Send(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
if (Target())
|
||||
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.
|
||||
status_t
|
||||
KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
KPPPLCP::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
if (protocolNumber != PPP_LCP_PROTOCOL) {
|
||||
ERROR("KPPPLCP::Receive(): wrong protocol number!\n");
|
||||
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
|
||||
int32 length = packet->m_len;
|
||||
if (packet->m_flags & M_PKTHDR)
|
||||
length = packet->m_pkthdr.len;
|
||||
length -= ntohs(data->length);
|
||||
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)
|
||||
|
||||
net_buffer *copy = gBufferModule->duplicate(packet);
|
||||
|
||||
if (ntohs(data.length) < 4)
|
||||
return B_ERROR;
|
||||
|
||||
bool handled = true;
|
||||
|
||||
switch (data->code) {
|
||||
switch (data.code) {
|
||||
case PPP_CONFIGURE_REQUEST:
|
||||
StateMachine().RCREvent(packet);
|
||||
break;
|
||||
@@ -310,43 +292,43 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
break;
|
||||
|
||||
default:
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
handled = false;
|
||||
}
|
||||
|
||||
|
||||
packet = copy;
|
||||
|
||||
|
||||
if (!packet)
|
||||
return handled ? B_OK : B_ERROR;
|
||||
|
||||
|
||||
status_t result = B_OK;
|
||||
|
||||
|
||||
// Try to find LCP extensions that can handle this code.
|
||||
// We must duplicate the packet in order to ask all handlers.
|
||||
int32 index = 0;
|
||||
KPPPLCPExtension *lcpExtension = LCPExtensionFor(data->code, &index);
|
||||
for (; lcpExtension; lcpExtension = LCPExtensionFor(data->code, &(++index))) {
|
||||
KPPPLCPExtension *lcpExtension = LCPExtensionFor(data.code, &index);
|
||||
for (; lcpExtension; lcpExtension = LCPExtensionFor(data.code, &(++index))) {
|
||||
if (!lcpExtension->IsEnabled())
|
||||
continue;
|
||||
|
||||
result = lcpExtension->Receive(packet, data->code);
|
||||
|
||||
|
||||
result = lcpExtension->Receive(packet, data.code);
|
||||
|
||||
// check return value and return it on error
|
||||
if (result == B_OK)
|
||||
handled = true;
|
||||
else if (result != PPP_UNHANDLED) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!handled) {
|
||||
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
|
||||
return PPP_REJECTED;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
|
||||
|
||||
gBufferModule->free(packet);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -356,7 +338,7 @@ void
|
||||
KPPPLCP::Pulse()
|
||||
{
|
||||
StateMachine().TimerEvent();
|
||||
|
||||
|
||||
for (int32 index = 0; index < CountLCPExtensions(); index++)
|
||||
LCPExtensionAt(index)->Pulse();
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ KPPPLCPExtension::InitCheck() const
|
||||
status_t
|
||||
KPPPLCPExtension::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
dprintf("KPPPLCPExtension::Control\n");
|
||||
switch (op) {
|
||||
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/*! \class KPPPLayer
|
||||
\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
|
||||
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
|
||||
@@ -19,13 +19,15 @@
|
||||
|
||||
#include <KPPPLayer.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <core_funcs.h>
|
||||
|
||||
extern net_buffer_module_info *gBufferModule;
|
||||
|
||||
/*! \brief Creates a new layer.
|
||||
|
||||
|
||||
If an error occurs in the constructor you should set \c fInitStatus.
|
||||
*/
|
||||
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.
|
||||
status_t
|
||||
KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
|
||||
KPPPLayer::SendToNext(net_buffer *packet, uint16 protocolNumber) const
|
||||
{
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
// Find the next possible handler for this packet.
|
||||
// Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything.
|
||||
if (Next()) {
|
||||
@@ -70,14 +72,14 @@ KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
|
||||
return Next()->SendToNext(packet, protocolNumber);
|
||||
} else {
|
||||
ERROR("KPPPLayer: SendToNext() failed because there is no next handler!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! \brief You may override this for periodic tasks.
|
||||
|
||||
|
||||
This method gets called every \c PPP_PULSE_RATE microseconds.
|
||||
*/
|
||||
void
|
||||
@@ -92,7 +94,7 @@ void
|
||||
KPPPLayer::SetName(const char *name)
|
||||
{
|
||||
free(fName);
|
||||
|
||||
|
||||
if (name)
|
||||
fName = strdup(name);
|
||||
else
|
||||
|
||||
@@ -60,6 +60,7 @@ KPPPOptionHandler::InitCheck() const
|
||||
status_t
|
||||
KPPPOptionHandler::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
dprintf("KPPPOptionHandler::Control\n");
|
||||
switch (op) {
|
||||
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||
{
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
#include <KPPPReportManager.h>
|
||||
|
||||
#include <LockerHelper.h>
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
#include <KPPPUtils.h>
|
||||
|
||||
|
||||
@@ -30,10 +32,10 @@ report_sender_thread(void *data)
|
||||
|
||||
|
||||
/*! \brief Constructor.
|
||||
|
||||
|
||||
\param lock The BLocker that should be used by this report manager.
|
||||
*/
|
||||
KPPPReportManager::KPPPReportManager(BLocker& lock)
|
||||
KPPPReportManager::KPPPReportManager(mutex& lock)
|
||||
: fLock(lock)
|
||||
{
|
||||
}
|
||||
@@ -48,10 +50,10 @@ KPPPReportManager::~KPPPReportManager()
|
||||
|
||||
|
||||
/*! \brief Send the given report message to the given thread.
|
||||
|
||||
|
||||
\param thread The report receiver.
|
||||
\param report The report message.
|
||||
|
||||
|
||||
\return \c false on error.
|
||||
*/
|
||||
bool
|
||||
@@ -59,7 +61,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
|
||||
{
|
||||
if (!report)
|
||||
return false;
|
||||
|
||||
|
||||
if (thread == find_thread(NULL)) {
|
||||
report_sender_info *info = new report_sender_info;
|
||||
info->thread = thread;
|
||||
@@ -68,7 +70,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
|
||||
B_NORMAL_PRIORITY, info));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
send_data_with_timeout(thread, PPP_REPORT_CODE, &report, sizeof(report),
|
||||
PPP_REPORT_TIMEOUT);
|
||||
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.
|
||||
|
||||
|
||||
\param type The type of report.
|
||||
\param thread The receiver thread.
|
||||
\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)
|
||||
return;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
ppp_report_request *request = new ppp_report_request;
|
||||
request->type = type;
|
||||
request->thread = thread;
|
||||
request->flags = flags;
|
||||
|
||||
|
||||
fReportRequests.AddItem(request);
|
||||
}
|
||||
|
||||
@@ -105,21 +107,21 @@ KPPPReportManager::DisableReports(ppp_report_type type, thread_id thread)
|
||||
{
|
||||
if (thread < 0)
|
||||
return;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
ppp_report_request *request;
|
||||
|
||||
|
||||
for (int32 i = 0; i < fReportRequests.CountItems(); i++) {
|
||||
request = fReportRequests.ItemAt(i);
|
||||
|
||||
|
||||
if (request->thread != thread)
|
||||
continue;
|
||||
|
||||
|
||||
if (request->type == type || type == PPP_ALL_REPORTS)
|
||||
fReportRequests.RemoveItem(request);
|
||||
}
|
||||
|
||||
|
||||
// empty message queue
|
||||
while (has_data(thread)) {
|
||||
thread_id sender;
|
||||
@@ -134,32 +136,32 @@ KPPPReportManager::DoesReport(ppp_report_type type, thread_id thread)
|
||||
{
|
||||
if (thread < 0)
|
||||
return false;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
ppp_report_request *request;
|
||||
|
||||
|
||||
for (int32 i = 0; i < fReportRequests.CountItems(); i++) {
|
||||
request = fReportRequests.ItemAt(i);
|
||||
|
||||
|
||||
if (request->thread == thread && request->type == type)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Send out report messages to all requestors.
|
||||
|
||||
|
||||
You may append additional data to the report messages. The data length may not be
|
||||
greater than \c PPP_REPORT_DATA_LIMIT.
|
||||
|
||||
|
||||
\param type The report type.
|
||||
\param code The report code belonging to the report type.
|
||||
\param data Additional data.
|
||||
\param length Length of the data.
|
||||
|
||||
|
||||
\return \c false on error.
|
||||
*/
|
||||
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",
|
||||
type, code, length, fReportRequests.CountItems());
|
||||
|
||||
|
||||
if (length > PPP_REPORT_DATA_LIMIT)
|
||||
return false;
|
||||
|
||||
|
||||
if (fReportRequests.CountItems() == 0)
|
||||
return true;
|
||||
|
||||
|
||||
if (!data)
|
||||
length = 0;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
|
||||
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
status_t result;
|
||||
thread_id me = find_thread(NULL);
|
||||
|
||||
|
||||
ppp_report_packet report;
|
||||
report.type = type;
|
||||
report.code = code;
|
||||
report.length = length;
|
||||
memcpy(report.data, data, length);
|
||||
|
||||
|
||||
ppp_report_request *request;
|
||||
|
||||
|
||||
for (int32 index = 0; index < fReportRequests.CountItems(); index++) {
|
||||
request = fReportRequests.ItemAt(index);
|
||||
|
||||
|
||||
// do not send to yourself
|
||||
if (request->thread == me)
|
||||
continue;
|
||||
|
||||
|
||||
result = send_data_with_timeout(request->thread, PPP_REPORT_CODE, &report,
|
||||
sizeof(report), PPP_REPORT_TIMEOUT);
|
||||
|
||||
|
||||
#if DEBUG
|
||||
if (result == B_TIMED_OUT)
|
||||
TRACE("KPPPReportManager::Report(): timed out sending\n");
|
||||
#endif
|
||||
|
||||
|
||||
if (result == B_BAD_THREAD_ID || result == B_NO_MEMORY
|
||||
|| request->flags & PPP_REMOVE_AFTER_REPORT) {
|
||||
fReportRequests.RemoveItem(request);
|
||||
@@ -212,6 +214,6 @@ KPPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 le
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,7 @@
|
||||
#define _K_PPP_CONFIGURE_PACKET__H
|
||||
|
||||
#include <TemplateList.h>
|
||||
|
||||
struct mbuf;
|
||||
#include <net_buffer.h>
|
||||
|
||||
//! An abstract configure item.
|
||||
typedef struct ppp_configure_item {
|
||||
@@ -29,7 +28,7 @@ class KPPPConfigurePacket {
|
||||
|
||||
public:
|
||||
KPPPConfigurePacket(uint8 code);
|
||||
KPPPConfigurePacket(struct mbuf *packet);
|
||||
KPPPConfigurePacket(net_buffer *packet);
|
||||
~KPPPConfigurePacket();
|
||||
|
||||
bool SetCode(uint8 code);
|
||||
@@ -52,8 +51,8 @@ class KPPPConfigurePacket {
|
||||
ppp_configure_item *ItemAt(int32 index) const;
|
||||
ppp_configure_item *ItemWithType(uint8 type) const;
|
||||
|
||||
struct mbuf *ToMbuf(uint32 MRU, uint32 reserve = 0);
|
||||
// the user is responsible for freeing the mbuf
|
||||
net_buffer *ToNetBuffer(uint32 MRU);
|
||||
// the user is responsible for freeing the net_buffer
|
||||
|
||||
private:
|
||||
uint8 fCode, fID;
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <KPPPDefs.h>
|
||||
#include <KPPPLayer.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
#ifndef _K_PPP_INTERFACE__H
|
||||
#include <KPPPInterface.h>
|
||||
#endif
|
||||
@@ -96,8 +98,8 @@ class KPPPDevice : public KPPPLayer {
|
||||
This should enqueue the packet and return immediately (never block).
|
||||
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 Receive(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||
|
||||
protected:
|
||||
//! Use this to set the device's maximum transfer unit (in bytes).
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
|
||||
#include <TemplateList.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <net_device.h>
|
||||
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
class KPPPDevice;
|
||||
class KPPPProtocol;
|
||||
class KPPPOptionHandler;
|
||||
@@ -48,6 +54,8 @@ class KPPPInterface : public KPPPLayer {
|
||||
KPPPInterface(const KPPPInterface& copy);
|
||||
KPPPInterface& operator= (const KPPPInterface& copy);
|
||||
|
||||
public:
|
||||
// we should set to private after finishing test
|
||||
// only PPPManager may construct us!
|
||||
KPPPInterface(const char *name, ppp_interface_entry *entry,
|
||||
ppp_interface_id ID, const driver_settings *settings,
|
||||
@@ -75,8 +83,8 @@ class KPPPInterface : public KPPPLayer {
|
||||
{ return fLCP; }
|
||||
|
||||
//! Returns the interfac's ifnet structure that is exported to the netstack.
|
||||
struct ifnet *Ifnet() const
|
||||
{ return fIfnet; }
|
||||
net_device *Ifnet() const
|
||||
{ return fIfnet; }
|
||||
|
||||
const char *Username() const;
|
||||
const char *Password() const;
|
||||
@@ -220,11 +228,11 @@ class KPPPInterface : public KPPPLayer {
|
||||
virtual bool IsAllowedToSend() const;
|
||||
// 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)
|
||||
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()!
|
||||
|
||||
void Pulse();
|
||||
@@ -255,7 +263,7 @@ class KPPPInterface : public KPPPLayer {
|
||||
ppp_interface_id fID;
|
||||
// the manager assigns an ID to every interface
|
||||
driver_settings *fSettings;
|
||||
struct ifnet *fIfnet;
|
||||
net_device *fIfnet;
|
||||
|
||||
char *fUsername, *fPassword;
|
||||
|
||||
@@ -288,7 +296,7 @@ class KPPPInterface : public KPPPLayer {
|
||||
KPPPStateMachine fStateMachine;
|
||||
KPPPLCP fLCP;
|
||||
KPPPReportManager fReportManager;
|
||||
BLocker& fLock;
|
||||
mutex& fLock;
|
||||
int32 fDeleteCounter;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include <KPPPStateMachine.h>
|
||||
#endif
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <NetBufferUtilities.h>
|
||||
|
||||
class KPPPLCPExtension;
|
||||
class KPPPOptionHandler;
|
||||
|
||||
@@ -79,15 +82,12 @@ class KPPPLCP : public KPPPProtocol {
|
||||
KPPPProtocol *Target() const
|
||||
{ return fTarget; }
|
||||
|
||||
uint32 AdditionalOverhead() const;
|
||||
// the overhead caused by the target, the device, and the interface
|
||||
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
virtual status_t Send(struct mbuf *packet,
|
||||
virtual status_t Send(net_buffer *packet,
|
||||
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();
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ class KPPPLCPExtension {
|
||||
// called by netstack (forwarded by KPPPInterface)
|
||||
|
||||
//! 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 Pulse();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <KPPPDefs.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
class KPPPLayer {
|
||||
protected:
|
||||
@@ -48,11 +49,11 @@ class KPPPLayer {
|
||||
virtual bool IsAllowedToSend() const = 0;
|
||||
|
||||
//! 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.
|
||||
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
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#ifndef _K_PPP_MANAGER__H
|
||||
#define _K_PPP_MANAGER__H
|
||||
|
||||
#include "net_module.h"
|
||||
#include <module.h>
|
||||
#include <net_device.h>
|
||||
#include <PPPControl.h>
|
||||
#include <PPPReportDefs.h>
|
||||
|
||||
|
||||
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "interfaces/ppp"
|
||||
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/KPPPManager/v1"
|
||||
|
||||
#define PPP_UNDEFINED_INTERFACE_ID 0
|
||||
// CreateInterface() returns this value on failure
|
||||
@@ -34,8 +34,7 @@ typedef struct ppp_interface_entry {
|
||||
deletes them when they are not needed anymore.
|
||||
*/
|
||||
typedef struct ppp_interface_module_info {
|
||||
kernel_net_module_info knminfo;
|
||||
//!< Exports needed network module functions.
|
||||
struct module_info info;
|
||||
|
||||
ppp_interface_id (*CreateInterface)(const driver_settings *settings,
|
||||
ppp_interface_id parentID);
|
||||
@@ -46,7 +45,9 @@ typedef struct ppp_interface_module_info {
|
||||
bool (*RemoveInterface)(ppp_interface_id ID);
|
||||
// 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);
|
||||
|
||||
status_t (*ControlInterface)(ppp_interface_id ID, uint32 op, void *data,
|
||||
|
||||
@@ -105,9 +105,9 @@ class KPPPProtocol : public KPPPLayer {
|
||||
virtual bool IsAllowedToSend() const;
|
||||
|
||||
//! 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.
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0;
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||
|
||||
protected:
|
||||
//! \brief Requests Up() to be called.
|
||||
|
||||
@@ -13,10 +13,13 @@
|
||||
|
||||
#include <TemplateList.h>
|
||||
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
|
||||
class KPPPReportManager {
|
||||
public:
|
||||
KPPPReportManager(BLocker& lock);
|
||||
KPPPReportManager(mutex& lock);
|
||||
~KPPPReportManager();
|
||||
|
||||
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)
|
||||
|
||||
private:
|
||||
BLocker& fLock;
|
||||
mutex& fLock;
|
||||
TemplateList<ppp_report_request*> fReportRequests;
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ class KPPPProtocol;
|
||||
#include <KPPPInterface.h>
|
||||
#endif
|
||||
|
||||
#include <Locker.h>
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
class PPPManager;
|
||||
class KPPPInterface;
|
||||
@@ -30,7 +31,7 @@ class KPPPStateMachine {
|
||||
// may only be constructed/destructed by KPPPInterface
|
||||
KPPPStateMachine(KPPPInterface& interface);
|
||||
~KPPPStateMachine();
|
||||
|
||||
|
||||
// copies are not allowed!
|
||||
KPPPStateMachine(const KPPPStateMachine& copy);
|
||||
KPPPStateMachine& operator= (const KPPPStateMachine& copy);
|
||||
@@ -42,28 +43,28 @@ class KPPPStateMachine {
|
||||
//! Returns the LCP protocol object belonging to this state machine.
|
||||
KPPPLCP& LCP() const
|
||||
{ return fLCP; }
|
||||
|
||||
|
||||
//! Returns the current state as defined in RFC 1661.
|
||||
ppp_state State() const
|
||||
{ return fState; }
|
||||
//! Returns the internal phase.
|
||||
ppp_phase Phase() const
|
||||
{ return fPhase; }
|
||||
|
||||
|
||||
uint8 NextID();
|
||||
|
||||
|
||||
//! Sets our packets' magic number. Used by Link-Quality-Monitoring.
|
||||
void SetMagicNumber(uint32 magicNumber)
|
||||
{ fMagicNumber = magicNumber; }
|
||||
//! Returns our packets' magic number.
|
||||
uint32 MagicNumber() const
|
||||
{ return fMagicNumber; }
|
||||
|
||||
|
||||
// public actions
|
||||
bool Reconfigure();
|
||||
bool SendEchoRequest();
|
||||
bool SendDiscardRequest();
|
||||
|
||||
|
||||
// public events:
|
||||
// NOTE: Local/PeerAuthenticationAccepted/Denied MUST be called before
|
||||
// Up(Failed)/DownEvent in order to allow changing the configuration of
|
||||
@@ -77,7 +78,7 @@ class KPPPStateMachine {
|
||||
//! Returns our local authentication status.
|
||||
ppp_authentication_status LocalAuthenticationStatus() const
|
||||
{ return fLocalAuthenticationStatus; }
|
||||
|
||||
|
||||
void PeerAuthenticationRequested();
|
||||
void PeerAuthenticationAccepted(const char *name);
|
||||
void PeerAuthenticationDenied(const char *name);
|
||||
@@ -87,17 +88,17 @@ class KPPPStateMachine {
|
||||
//! Returns the peer's authentication status.
|
||||
ppp_authentication_status PeerAuthenticationStatus() const
|
||||
{ return fPeerAuthenticationStatus; }
|
||||
|
||||
|
||||
// sub-interface events
|
||||
void UpFailedEvent(KPPPInterface& interface);
|
||||
void UpEvent(KPPPInterface& interface);
|
||||
void DownEvent(KPPPInterface& interface);
|
||||
|
||||
|
||||
// protocol events
|
||||
void UpFailedEvent(KPPPProtocol *protocol);
|
||||
void UpEvent(KPPPProtocol *protocol);
|
||||
void DownEvent(KPPPProtocol *protocol);
|
||||
|
||||
|
||||
// device events
|
||||
bool TLSNotify();
|
||||
bool TLFNotify();
|
||||
@@ -109,30 +110,30 @@ class KPPPStateMachine {
|
||||
// private StateMachine methods
|
||||
void NewState(ppp_state next);
|
||||
void NewPhase(ppp_phase next);
|
||||
|
||||
|
||||
// private events
|
||||
void OpenEvent();
|
||||
void ContinueOpenEvent();
|
||||
void CloseEvent();
|
||||
void TOGoodEvent();
|
||||
void TOBadEvent();
|
||||
void RCRGoodEvent(struct mbuf *packet);
|
||||
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject);
|
||||
void RCAEvent(struct mbuf *packet);
|
||||
void RCNEvent(struct mbuf *packet);
|
||||
void RTREvent(struct mbuf *packet);
|
||||
void RTAEvent(struct mbuf *packet);
|
||||
void RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
||||
void RCRGoodEvent(net_buffer *packet);
|
||||
void RCRBadEvent(net_buffer *nak, net_buffer *reject);
|
||||
void RCAEvent(net_buffer *packet);
|
||||
void RCNEvent(net_buffer *packet);
|
||||
void RTREvent(net_buffer *packet);
|
||||
void RTAEvent(net_buffer *packet);
|
||||
void RUCEvent(net_buffer *packet, uint16 protocolNumber,
|
||||
uint8 code = PPP_PROTOCOL_REJECT);
|
||||
void RXJGoodEvent(struct mbuf *packet);
|
||||
void RXJBadEvent(struct mbuf *packet);
|
||||
void RXREvent(struct mbuf *packet);
|
||||
|
||||
void RXJGoodEvent(net_buffer *packet);
|
||||
void RXJBadEvent(net_buffer *packet);
|
||||
void RXREvent(net_buffer *packet);
|
||||
|
||||
// general events (for Good/Bad events)
|
||||
void TimerEvent();
|
||||
void RCREvent(struct mbuf *packet);
|
||||
void RXJEvent(struct mbuf *packet);
|
||||
|
||||
void RCREvent(net_buffer *packet);
|
||||
void RXJEvent(net_buffer *packet);
|
||||
|
||||
// actions
|
||||
void IllegalEvent(ppp_event event);
|
||||
void ThisLayerUp();
|
||||
@@ -142,42 +143,42 @@ class KPPPStateMachine {
|
||||
void InitializeRestartCount();
|
||||
void ZeroRestartCount();
|
||||
bool SendConfigureRequest();
|
||||
bool SendConfigureAck(struct mbuf *packet);
|
||||
bool SendConfigureNak(struct mbuf *packet);
|
||||
bool SendConfigureAck(net_buffer *packet);
|
||||
bool SendConfigureNak(net_buffer *packet);
|
||||
bool SendTerminateRequest();
|
||||
bool SendTerminateAck(struct mbuf *request = NULL);
|
||||
bool SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code);
|
||||
bool SendEchoReply(struct mbuf *request);
|
||||
|
||||
bool SendTerminateAck(net_buffer *request = NULL);
|
||||
bool SendCodeReject(net_buffer *packet, uint16 protocolNumber, uint8 code);
|
||||
bool SendEchoReply(net_buffer *request);
|
||||
|
||||
void BringProtocolsUp();
|
||||
uint32 BringPhaseUp();
|
||||
|
||||
|
||||
void DownProtocols();
|
||||
void ResetLCPHandlers();
|
||||
|
||||
private:
|
||||
KPPPInterface& fInterface;
|
||||
KPPPLCP& fLCP;
|
||||
|
||||
|
||||
ppp_state fState;
|
||||
ppp_phase fPhase;
|
||||
|
||||
vint32 fID;
|
||||
|
||||
int32 fID;
|
||||
uint32 fMagicNumber;
|
||||
int32 fLastConnectionReportCode;
|
||||
|
||||
|
||||
ppp_authentication_status fLocalAuthenticationStatus,
|
||||
fPeerAuthenticationStatus;
|
||||
char *fLocalAuthenticationName, *fPeerAuthenticationName;
|
||||
|
||||
|
||||
// counters and timers
|
||||
int32 fMaxRequest, fMaxTerminate, fMaxNak;
|
||||
int32 fRequestCounter, fTerminateCounter, fNakCounter;
|
||||
uint8 fRequestID, fTerminateID, fEchoID;
|
||||
// the ID we used for the last configure/terminate/echo request
|
||||
bigtime_t fNextTimeout;
|
||||
|
||||
BLocker fLock;
|
||||
|
||||
mutex fLock;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,76 @@
|
||||
#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
|
||||
#define PPP_HANDLER_NAME_LENGTH_LIMIT 63
|
||||
// if the name is longer than this value it will be truncated to fit the structure
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
#include <directories.h>
|
||||
|
||||
#include "net_module.h"
|
||||
|
||||
|
||||
typedef uint32 ppp_interface_id;
|
||||
|
||||
@@ -37,7 +35,8 @@ typedef uint32 ppp_interface_id;
|
||||
#define PPP_SERVER_MODE_VALUE "Server"
|
||||
|
||||
// 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 \
|
||||
kUserSettingsDirectory "/kernel/drivers/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.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||
headers ] : true ;
|
||||
@@ -19,18 +20,18 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
|
||||
StaticLibrary libppp.a :
|
||||
strlcat.c
|
||||
driver_settings.c
|
||||
driver_settings.cpp
|
||||
settings_tools.cpp
|
||||
KPPPUtils.cpp
|
||||
|
||||
_libppputils.cpp
|
||||
|
||||
PPPInterface.cpp
|
||||
PPPInterfaceListener.cpp
|
||||
PPPManager.cpp
|
||||
MessageDriverSettingsUtils.cpp
|
||||
: libnetwork.so libbnetapi.so
|
||||
;
|
||||
|
||||
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 KPPPUtils.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
|
||||
|
||||
@@ -13,13 +13,20 @@
|
||||
#include "PPPInterface.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <unistd.h>
|
||||
#include "_libppputils.h"
|
||||
|
||||
#include <Path.h>
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <NetworkDevice.h>
|
||||
#include <NetworkInterface.h>
|
||||
|
||||
|
||||
/*! \brief Sets the interface to \a ID.
|
||||
|
||||
@@ -27,7 +34,9 @@
|
||||
*/
|
||||
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);
|
||||
}
|
||||
@@ -36,7 +45,10 @@ PPPInterface::PPPInterface(ppp_interface_id ID)
|
||||
//! Copy constructor.
|
||||
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());
|
||||
}
|
||||
@@ -45,6 +57,7 @@ PPPInterface::PPPInterface(const PPPInterface& copy)
|
||||
//! Destructor.
|
||||
PPPInterface::~PPPInterface()
|
||||
{
|
||||
// printf("Destructor\n");
|
||||
if (fFD >= 0)
|
||||
close(fFD);
|
||||
}
|
||||
@@ -64,6 +77,7 @@ PPPInterface::InitCheck() const
|
||||
{
|
||||
if (fFD < 0)
|
||||
return B_ERROR;
|
||||
|
||||
if (fID == PPP_UNDEFINED_INTERFACE_ID)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
@@ -87,19 +101,29 @@ PPPInterface::InitCheck() const
|
||||
status_t
|
||||
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;
|
||||
}
|
||||
|
||||
fID = ID;
|
||||
|
||||
ppp_interface_info_t info;
|
||||
// printf("SetTo info:%p\n", &info);
|
||||
if (GetInterfaceInfo(&info)) {
|
||||
fName = info.info.name;
|
||||
fID = ID;
|
||||
// printf("%s fine: name:%s, fID:%ld\n", __func__, info.info.name, fID);
|
||||
} else {
|
||||
fName = "";
|
||||
fID = PPP_UNDEFINED_INTERFACE_ID;
|
||||
// printf("%s fail: name:%s, fID:%ld\n", __func__, "", fID);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// printf("Set To %ld end =============================\n", ID);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -119,23 +143,32 @@ PPPInterface::SetTo(ppp_interface_id ID)
|
||||
status_t
|
||||
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();
|
||||
|
||||
ppp_control_info control;
|
||||
}
|
||||
|
||||
ppp_control_info info;
|
||||
control_net_module_args args;
|
||||
|
||||
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||
args.op = PPPC_CONTROL_INTERFACE;
|
||||
args.data = &control;
|
||||
args.length = sizeof(control);
|
||||
|
||||
control.index = ID();
|
||||
control.op = op;
|
||||
control.data = data;
|
||||
control.length = length;
|
||||
|
||||
return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args);
|
||||
args.data = &info;
|
||||
args.length = sizeof(ppp_control_info);
|
||||
|
||||
info.index = ID();
|
||||
info.op = op;
|
||||
info.data = data;
|
||||
info.length = length;
|
||||
|
||||
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
|
||||
PPPInterface::SetUsername(const char *username) const
|
||||
{
|
||||
printf("PPPInterface::SetUsername\n");
|
||||
if (InitCheck() != B_OK || !username)
|
||||
return false;
|
||||
|
||||
@@ -155,6 +189,7 @@ PPPInterface::SetUsername(const char *username) const
|
||||
bool
|
||||
PPPInterface::SetPassword(const char *password) const
|
||||
{
|
||||
printf("PPPInterface::SetPassword\n");
|
||||
if (InitCheck() != B_OK || !password)
|
||||
return false;
|
||||
|
||||
@@ -167,6 +202,7 @@ PPPInterface::SetPassword(const char *password) const
|
||||
bool
|
||||
PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
|
||||
{
|
||||
printf("PPPInterface::SetAskBeforeConnecting\n");
|
||||
if (InitCheck() != B_OK)
|
||||
return false;
|
||||
|
||||
@@ -188,6 +224,7 @@ PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
|
||||
status_t
|
||||
PPPInterface::GetSettingsEntry(BEntry *entry) const
|
||||
{
|
||||
printf("PPPInterface::GetSettingsEntry\n");
|
||||
if (InitCheck() != B_OK)
|
||||
return InitCheck();
|
||||
else if (!entry || strlen(Name()) == 0)
|
||||
@@ -205,10 +242,103 @@ PPPInterface::GetSettingsEntry(BEntry *entry) const
|
||||
bool
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -222,6 +352,7 @@ PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
|
||||
bool
|
||||
PPPInterface::GetStatistics(ppp_statistics *statistics) const
|
||||
{
|
||||
printf("PPPInterface::GetStatistics\n");
|
||||
if (!statistics)
|
||||
return false;
|
||||
|
||||
@@ -233,6 +364,7 @@ PPPInterface::GetStatistics(ppp_statistics *statistics) const
|
||||
bool
|
||||
PPPInterface::HasSettings(const driver_settings *settings) const
|
||||
{
|
||||
printf("PPPInterface::HasSettings\n");
|
||||
if (InitCheck() != B_OK || !settings)
|
||||
return false;
|
||||
|
||||
@@ -250,9 +382,24 @@ PPPInterface::Up() const
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
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();
|
||||
control_net_module_args args;
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||
args.op = PPPC_BRING_INTERFACE_UP;
|
||||
args.data = &id;
|
||||
@@ -268,9 +415,24 @@ PPPInterface::Down() const
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
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();
|
||||
control_net_module_args args;
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||
args.op = PPPC_BRING_INTERFACE_DOWN;
|
||||
args.data = &id;
|
||||
@@ -292,6 +454,7 @@ bool
|
||||
PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
|
||||
int32 flags) const
|
||||
{
|
||||
printf("PPPInterface::EnableReports\n");
|
||||
ppp_report_request request;
|
||||
request.type = type;
|
||||
request.thread = thread;
|
||||
@@ -311,6 +474,7 @@ PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
|
||||
bool
|
||||
PPPInterface::DisableReports(ppp_report_type type, thread_id thread) const
|
||||
{
|
||||
printf("PPPInterface::DisableReports\n");
|
||||
ppp_report_request request;
|
||||
request.type = type;
|
||||
request.thread = thread;
|
||||
|
||||
@@ -20,16 +20,49 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <settings_tools.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.
|
||||
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;
|
||||
|
||||
control_net_module_args args;
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||
args.op = op;
|
||||
args.data = data;
|
||||
@@ -169,6 +203,7 @@ PPPManager::ControlModule(const char *name, uint32 op, void *data,
|
||||
return B_ERROR;
|
||||
|
||||
control_net_module_args args;
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = name;
|
||||
args.op = op;
|
||||
args.data = data;
|
||||
@@ -207,13 +242,72 @@ PPPManager::CreateInterface(const driver_settings *settings) const
|
||||
ppp_interface_id
|
||||
PPPManager::CreateInterfaceWithName(const char *name) const
|
||||
{
|
||||
ppp_interface_description_info info;
|
||||
info.u.name = name;
|
||||
ppp_interface_id ID = InterfaceWithName(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
|
||||
while (true) {
|
||||
requestCount = *count = CountInterfaces(filter);
|
||||
if (*count == -1)
|
||||
if (*count <= 0) {
|
||||
printf("No interface, count, first round:%ld\n", *count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
requestCount += 10;
|
||||
// request some more interfaces in case some are added in the mean time
|
||||
interfaces = new ppp_interface_id[requestCount];
|
||||
// printf("interfaces addr: %p\n, requestCount: %ld", interfaces, requestCount);
|
||||
*count = GetInterfaces(interfaces, requestCount, filter);
|
||||
if (*count == -1) {
|
||||
if (*count <= 0) {
|
||||
printf("No interface, count second round:%ld\n", *count);
|
||||
delete interfaces;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (*count < requestCount)
|
||||
break;
|
||||
|
||||
@@ -345,12 +443,17 @@ PPPManager::InterfaceWithName(const char *name) const
|
||||
int32 count;
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
// printf("first ID:%ld count:%ld\n", interfaces[0], count);
|
||||
|
||||
ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
|
||||
PPPInterface interface;
|
||||
ppp_interface_info_t info;
|
||||
// printf("internal info is at: %p\n", &info);
|
||||
|
||||
for (int32 index = 0; index < count; 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.
|
||||
int32
|
||||
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 GetStatistics(ppp_statistics *statistics) 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 Down() const;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef _PPP_MANAGER__H
|
||||
#define _PPP_MANAGER__H
|
||||
|
||||
#include <Directory.h>
|
||||
#include <KPPPManager.h>
|
||||
#include <String.h>
|
||||
|
||||
@@ -33,6 +34,7 @@ class PPPManager {
|
||||
ppp_interface_id CreateInterface(const driver_settings *settings) const;
|
||||
ppp_interface_id CreateInterfaceWithName(const char *name) const;
|
||||
bool DeleteInterface(ppp_interface_id ID) const;
|
||||
bool DeleteInterface(const char* name) const;
|
||||
|
||||
ppp_interface_id *Interfaces(int32 *count,
|
||||
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const;
|
||||
|
||||
@@ -833,6 +833,9 @@ init_stack()
|
||||
// TODO: for now!
|
||||
register_domain_datalink_protocols(AF_INET, IFT_LOOP,
|
||||
"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,
|
||||
"network/datalink_protocols/loopback_frame/v1", NULL);
|
||||
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 mount_nfs ;
|
||||
SubInclude HAIKU_TOP src bin network netstat ;
|
||||
#SubInclude HAIKU_TOP src bin network pppconfig ;
|
||||
#SubInclude HAIKU_TOP src bin network ppp_up ;
|
||||
SubInclude HAIKU_TOP src bin network pppconfig ;
|
||||
SubInclude HAIKU_TOP src bin network ppp_up ;
|
||||
SubInclude HAIKU_TOP src bin network ping ;
|
||||
SubInclude HAIKU_TOP src bin network ping6 ;
|
||||
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) ;
|
||||
|
||||
@@ -8,7 +8,10 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
||||
# 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
|
||||
headers ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
@@ -24,7 +27,7 @@ BinCommand ppp_up :
|
||||
PPPStatusWindow.cpp
|
||||
PPPUpApplication.cpp
|
||||
:
|
||||
libppp.a be
|
||||
libppp.a be $(TARGET_LIBSUPC++) translation $(HAIKU_LOCALE_LIBS) root $(TARGET_NETWORK_LIBS)
|
||||
;
|
||||
|
||||
# Installation
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
#ifndef STATUS_VIEW__H
|
||||
#define STATUS_VIEW__H
|
||||
|
||||
#include <View.h>
|
||||
#include <Button.h>
|
||||
#include <PPPInterface.h>
|
||||
#include <StringView.h>
|
||||
|
||||
|
||||
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) ;
|
||||
|
||||
@@ -8,6 +8,7 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||
headers ] : true ;
|
||||
@@ -17,7 +18,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
BinCommand pppconfig :
|
||||
pppconfig.cpp
|
||||
:
|
||||
be libppp.a
|
||||
be libppp.a $(TARGET_LIBSUPC++) $(TARGET_NETWORK_LIBS)
|
||||
;
|
||||
|
||||
# Installation -- in the test directory for the time being
|
||||
|
||||
@@ -40,33 +40,35 @@ status_t
|
||||
show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
||||
{
|
||||
PPPManager manager;
|
||||
if(manager.InitCheck() != B_OK) {
|
||||
if (manager.InitCheck() != B_OK) {
|
||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32 count;
|
||||
int32 count = 0;
|
||||
ppp_interface_id *interfaces = manager.Interfaces(&count, filter);
|
||||
|
||||
if(!interfaces) {
|
||||
if (!interfaces || count <= 0) {
|
||||
fprintf(stderr, "Error: Could not get interfaces information!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
fprintf(stderr, "Get %ld ppp interfaces, first is %ld!\n", count, interfaces[0]);
|
||||
|
||||
ppp_interface_info_t info;
|
||||
PPPInterface interface;
|
||||
|
||||
printf("Listing PPP interfaces:\n");
|
||||
|
||||
// print out information for each interface
|
||||
for(int32 index = 0; index < count; index++) {
|
||||
for (int32 index = 0; index < count; index++) {
|
||||
interface.SetTo(interfaces[index]);
|
||||
if(interface.InitCheck() == B_OK) {
|
||||
if (interface.InitCheck() == B_OK) {
|
||||
interface.GetInterfaceInfo(&info);
|
||||
printf("\n");
|
||||
|
||||
// type and unit (if it has one)
|
||||
if(info.info.if_unit >= 0) {
|
||||
if (info.info.if_unit >= 0) {
|
||||
printf("Type: Visible\n");
|
||||
printf("\tInterface: ppp%ld\n", info.info.if_unit);
|
||||
} else
|
||||
@@ -79,9 +81,9 @@ show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
||||
|
||||
// mode
|
||||
printf("\tMode: ");
|
||||
if(info.info.mode == PPP_CLIENT_MODE)
|
||||
if (info.info.mode == PPP_CLIENT_MODE)
|
||||
printf("Client\n");
|
||||
else if(info.info.mode == PPP_SERVER_MODE)
|
||||
else if (info.info.mode == PPP_SERVER_MODE)
|
||||
printf("Server\n");
|
||||
else
|
||||
printf("Unknown\n");
|
||||
@@ -118,13 +120,13 @@ status_t
|
||||
create(const char *name, bool bringUp = true)
|
||||
{
|
||||
PPPManager manager;
|
||||
if(manager.InitCheck() != B_OK) {
|
||||
if (manager.InitCheck() != B_OK) {
|
||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
@@ -134,13 +136,13 @@ create(const char *name, bool bringUp = true)
|
||||
ppp_interface_info_t 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);
|
||||
else
|
||||
printf("This interface is hidden! You can delete it by typing:\n"
|
||||
"pppconfig delete %ld\n", interface.ID());
|
||||
|
||||
if(bringUp) {
|
||||
if (bringUp) {
|
||||
interface.Up();
|
||||
printf("Connecting in background...\n");
|
||||
}
|
||||
@@ -153,22 +155,22 @@ static
|
||||
status_t
|
||||
connect(const char *name)
|
||||
{
|
||||
if(!name || strlen(name) == 0)
|
||||
if (!name || strlen(name) == 0)
|
||||
return -1;
|
||||
|
||||
PPPManager manager;
|
||||
if(manager.InitCheck() != B_OK) {
|
||||
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) {
|
||||
if (interface.InitCheck() != B_OK) {
|
||||
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!interface.Up()) {
|
||||
if (!interface.Up()) {
|
||||
fprintf(stderr, "Error: Could not connect!\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -181,24 +183,435 @@ connect(const char *name)
|
||||
|
||||
static
|
||||
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;
|
||||
|
||||
if (!user || strlen(user) == 0)
|
||||
return -1;
|
||||
|
||||
PPPManager manager;
|
||||
if(manager.InitCheck() != B_OK) {
|
||||
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) {
|
||||
if (interface.InitCheck() != B_OK) {
|
||||
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
@@ -211,16 +624,16 @@ static
|
||||
status_t
|
||||
delete_interface(const char *name)
|
||||
{
|
||||
if(!name || strlen(name) == 0)
|
||||
if (!name || strlen(name) == 0)
|
||||
return -1;
|
||||
|
||||
PPPManager manager;
|
||||
if(manager.InitCheck() != B_OK) {
|
||||
if (manager.InitCheck() != B_OK) {
|
||||
fprintf(stderr, "Error: Could not load interface manager!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!manager.DeleteInterface(manager.InterfaceWithName(name))) {
|
||||
if (!manager.DeleteInterface(name)) {
|
||||
fprintf(stderr, "Error: Could not delete interface!\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -233,26 +646,33 @@ static
|
||||
status_t
|
||||
show_details(const char *name)
|
||||
{
|
||||
if(!name || strlen(name) == 0)
|
||||
if (!name || strlen(name) == 0)
|
||||
return -1;
|
||||
|
||||
PPPManager manager;
|
||||
if(manager.InitCheck() != B_OK) {
|
||||
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) {
|
||||
ppp_interface_id ID = manager.InterfaceWithName(name);
|
||||
if (ID <= 0) {
|
||||
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||
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;
|
||||
// printf("ppp_interface_info_t addr:%p\n", &info);
|
||||
interface.GetInterfaceInfo(&info);
|
||||
|
||||
// type and name (if it has one)
|
||||
if(info.info.if_unit >= 0) {
|
||||
if (info.info.if_unit >= 0) {
|
||||
printf("Type: Visible\n");
|
||||
printf("Interface: ppp%ld\n", info.info.if_unit);
|
||||
} else
|
||||
@@ -277,9 +697,9 @@ show_details(const char *name)
|
||||
|
||||
// mode
|
||||
printf("Mode: ");
|
||||
if(info.info.mode == PPP_CLIENT_MODE)
|
||||
if (info.info.mode == PPP_CLIENT_MODE)
|
||||
printf("Client\n");
|
||||
else if(info.info.mode == PPP_SERVER_MODE)
|
||||
else if (info.info.mode == PPP_SERVER_MODE)
|
||||
printf("Server\n");
|
||||
else
|
||||
printf("Unknown\n");
|
||||
@@ -310,24 +730,51 @@ show_details(const char *name)
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
if(argc == 2) {
|
||||
if(!strcmp(argv[1], "show") || !strcmp(argv[1], "-a"))
|
||||
if (argc == 2) {
|
||||
if (!strcmp(argv[1], "show") || !strcmp(argv[1], "-a"))
|
||||
return show(PPP_ALL_INTERFACES);
|
||||
else
|
||||
return print_help();
|
||||
}if(argc == 3) {
|
||||
if(!strcmp(argv[1], "init"))
|
||||
}if (argc == 3) {
|
||||
if (!strcmp(argv[1], "init"))
|
||||
return create(argv[2], false);
|
||||
else if(!strcmp(argv[1], "create"))
|
||||
else if (!strcmp(argv[1], "create"))
|
||||
return create(argv[2], true);
|
||||
else if(!strcmp(argv[1], "connect"))
|
||||
else if (!strcmp(argv[1], "connect"))
|
||||
return connect(argv[2]);
|
||||
else if(!strcmp(argv[1], "disconnect"))
|
||||
else if (!strcmp(argv[1], "disconnect"))
|
||||
return disconnect(argv[2]);
|
||||
else if(!strcmp(argv[1], "delete"))
|
||||
else if (!strcmp(argv[1], "delete"))
|
||||
return delete_interface(argv[2]);
|
||||
else if(!strcmp(argv[1], "details"))
|
||||
else if (!strcmp(argv[1], "details"))
|
||||
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
|
||||
return print_help();
|
||||
} else
|
||||
|
||||
Reference in New Issue
Block a user