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:
mshlyn
2016-01-02 07:22:13 -05:00
committed by Augustin Cavalier
parent 7121057cb7
commit e3724c38cb
62 changed files with 5214 additions and 2293 deletions
+1 -1
View File
@@ -134,7 +134,7 @@ SYSTEM_NETWORK_DATALINK_PROTOCOLS =
loopback_frame loopback_frame
; ;
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe ; #SYSTEM_NETWORK_PPP = ipcp modem pap pppoe KPPPManager ;
SYSTEM_NETWORK_PROTOCOLS = SYSTEM_NETWORK_PROTOCOLS =
icmp icmp6 ipv4 ipv6 icmp icmp6 ipv4 ipv6
+1 -1
View File
@@ -250,7 +250,7 @@ AddFilesToPackage add-ons kernel network : dns_resolver ;
AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ; AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ;
AddFilesToPackage add-ons kernel network datalink_protocols AddFilesToPackage add-ons kernel network datalink_protocols
: $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ; : $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ;
AddFilesToPackage add-ons kernel network ppp: $(SYSTEM_NETWORK_PPP) ; AddFilesToPackage add-ons kernel network ppp : $(SYSTEM_NETWORK_PPP) ;
AddFilesToPackage add-ons kernel network protocols AddFilesToPackage add-ons kernel network protocols
: $(SYSTEM_NETWORK_PROTOCOLS) ; : $(SYSTEM_NETWORK_PROTOCOLS) ;
+1 -1
View File
@@ -209,7 +209,7 @@ AddFilesToPackage add-ons kernel network : dns_resolver ;
AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ; AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ;
AddFilesToPackage add-ons kernel network datalink_protocols AddFilesToPackage add-ons kernel network datalink_protocols
: $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ; : $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ;
AddFilesToPackage add-ons kernel network ppp: $(SYSTEM_NETWORK_PPP) ; AddFilesToPackage add-ons kernel network ppp : $(SYSTEM_NETWORK_PPP) ;
AddFilesToPackage add-ons kernel network protocols AddFilesToPackage add-ons kernel network protocols
: $(SYSTEM_NETWORK_PROTOCOLS) ; : $(SYSTEM_NETWORK_PROTOCOLS) ;
+1
View File
@@ -6,3 +6,4 @@ SubInclude HAIKU_TOP src add-ons kernel network dns_resolver ;
SubInclude HAIKU_TOP src add-ons kernel network notifications ; SubInclude HAIKU_TOP src add-ons kernel network notifications ;
SubInclude HAIKU_TOP src add-ons kernel network protocols ; SubInclude HAIKU_TOP src add-ons kernel network protocols ;
SubInclude HAIKU_TOP src add-ons kernel network stack ; SubInclude HAIKU_TOP src add-ons kernel network stack ;
SubInclude HAIKU_TOP src add-ons kernel network ppp ;
+4 -1
View File
@@ -1,7 +1,10 @@
SubDir HAIKU_TOP src add-ons kernel network ppp ; SubDir HAIKU_TOP src add-ons kernel network ppp ;
SubInclude HAIKU_TOP src add-ons kernel network ppp ipcp ; SubInclude HAIKU_TOP src add-ons kernel network ppp ipcp ;
SubInclude HAIKU_TOP src add-ons kernel network ppp modem ; # SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
SubInclude HAIKU_TOP src add-ons kernel network ppp pap ; SubInclude HAIKU_TOP src add-ons kernel network ppp pap ;
SubInclude HAIKU_TOP src add-ons kernel network ppp pppoe ; SubInclude HAIKU_TOP src add-ons kernel network ppp pppoe ;
SubInclude HAIKU_TOP src add-ons kernel network ppp shared ; SubInclude HAIKU_TOP src add-ons kernel network ppp shared ;
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp ;
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
+26 -16
View File
@@ -1,41 +1,51 @@
SubDir HAIKU_TOP src add-ons kernel network ppp ipcp ; SubDir HAIKU_TOP src add-ons kernel network ppp ipcp ;
SetSubDirSupportedPlatformsBeOSCompatible ; SetSubDirSupportedPlatformsBeOSCompatible ;
SubDirC++Flags -fno-rtti ;
if $(TARGET_PLATFORM) != haiku { if $(TARGET_PLATFORM) != haiku {
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ; UseHeaders [ FStandardOSHeaders ] : true ;
# We need the public network headers also when not compiling for Haiku. # Needed for the atomic_add64() prototype.
# Unfortunately we get more than we want, namely all POSIX headers.
} }
# for kernel_cpp.h and BLocker UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ; # We need the public network headers also when not compiling for Haiku.
# Unfortunately we get more than we want, namely all POSIX headers.
UsePrivateKernelHeaders ;
UsePrivateHeaders net ; UsePrivateHeaders net ;
UsePrivateHeaders libroot net ;
UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel ] ;
UsePrivateHeaders [ FDirName kernel util ] ; UsePrivateHeaders [ FDirName kernel util ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
libkernelppp headers ] : true ; libkernelppp headers ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp pppoe
] : true ;
{
SubDirC++Flags -fno-rtti ;
}
KernelAddon ipcp : KernelAddon ipcp :
# imported from libnet atomic.S
kernel_cpp.cpp
# imported from kernel util
inet_addr.c inet_addr.c
ipcp.cpp ipcp.cpp
Protocol.cpp Protocol.cpp
; ;
SEARCH on [ FGristFiles inet_addr.c ] SEARCH on [ FGristFiles inet_addr.c ]
= [ FDirName $(HAIKU_TOP) src kits network compat libnet ] ; = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
SEARCH on [ FGristFiles kernel_cpp.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
SEARCH on [ FGristFiles atomic.S ]
= [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
LinkAgainst ipcp : libkernelppp.a ; LinkAgainst ipcp : libkernelppp.a ;
# Installation
HaikuInstall install-networking HaikuInstall install-networking
: /boot/home/config/add-ons/kernel/obos_network/ppp : /boot/home/config/add-ons/kernel/network/ppp
: ipcp ; : ipcp ;
File diff suppressed because it is too large Load Diff
+33 -31
View File
@@ -9,9 +9,11 @@
#include <driver_settings.h> #include <driver_settings.h>
#include <KPPPProtocol.h> #include <KPPPProtocol.h>
#include <Locker.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <net_datalink.h>
#include <net_datalink_protocol.h>
#include <net/route.h>
#define IPCP_PROTOCOL 0x8021 #define IPCP_PROTOCOL 0x8021
@@ -60,46 +62,46 @@ class IPCP : public KPPPProtocol {
public: public:
IPCP(KPPPInterface& interface, driver_parameter *settings); IPCP(KPPPInterface& interface, driver_parameter *settings);
virtual ~IPCP(); virtual ~IPCP();
virtual void Uninit(); virtual void Uninit();
ppp_state State() const ppp_state State() const
{ return fState; } { return fState; }
virtual status_t StackControl(uint32 op, void *data); virtual status_t StackControl(uint32 op, void *data);
virtual bool Up(); virtual bool Up();
virtual bool Down(); virtual bool Down();
virtual status_t Send(struct mbuf *packet, virtual status_t Send(net_buffer *packet,
uint16 protocolNumber = IPCP_PROTOCOL); uint16 protocolNumber = IPCP_PROTOCOL);
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
status_t ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber); status_t ReceiveIPPacket(net_buffer *packet, uint16 protocolNumber);
virtual void Pulse(); virtual void Pulse();
private: private:
bool ParseSideRequests(const driver_parameter *requests, ppp_side side); bool ParseSideRequests(const driver_parameter *requests, ppp_side side);
void UpdateAddresses(); void UpdateAddresses();
void RemoveRoutes(); void RemoveRoutes();
// for state machine // for state machine
void NewState(ppp_state next); void NewState(ppp_state next);
uint8 NextID(); uint8 NextID();
// return the next id for IPCP packets // return the next id for IPCP packets
// events // events
void TOGoodEvent(); void TOGoodEvent();
void TOBadEvent(); void TOBadEvent();
void RCREvent(struct mbuf *packet); void RCREvent(net_buffer *packet);
void RCRGoodEvent(struct mbuf *packet); void RCRGoodEvent(net_buffer *packet);
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject); void RCRBadEvent(net_buffer *nak, net_buffer *reject);
void RCAEvent(struct mbuf *packet); void RCAEvent(net_buffer *packet);
void RCNEvent(struct mbuf *packet); void RCNEvent(net_buffer *packet);
void RTREvent(struct mbuf *packet); void RTREvent(net_buffer *packet);
void RTAEvent(struct mbuf *packet); void RTAEvent(net_buffer *packet);
void RUCEvent(struct mbuf *packet); void RUCEvent(net_buffer *packet);
void RXJBadEvent(struct mbuf *packet); void RXJBadEvent(net_buffer *packet);
// actions // actions
void IllegalEvent(ppp_event event); void IllegalEvent(ppp_event event);
void ReportUpFailedEvent(); void ReportUpFailedEvent();
@@ -108,27 +110,27 @@ class IPCP : public KPPPProtocol {
void InitializeRestartCount(); void InitializeRestartCount();
void ResetRestartCount(); void ResetRestartCount();
bool SendConfigureRequest(); bool SendConfigureRequest();
bool SendConfigureAck(struct mbuf *packet); bool SendConfigureAck(net_buffer *packet);
bool SendConfigureNak(struct mbuf *packet); bool SendConfigureNak(net_buffer *packet);
bool SendTerminateRequest(); bool SendTerminateRequest();
bool SendTerminateAck(struct mbuf *request = NULL); bool SendTerminateAck(net_buffer *request = NULL);
bool SendCodeReject(struct mbuf *packet); bool SendCodeReject(net_buffer *packet);
private: private:
ipcp_configuration fLocalConfiguration, fPeerConfiguration; ipcp_configuration fLocalConfiguration, fPeerConfiguration;
ipcp_requests fLocalRequests, fPeerRequests; ipcp_requests fLocalRequests, fPeerRequests;
// default route // default route
struct sockaddr_in fGateway; struct sockaddr_in fGateway;
rtentry *fDefaultRoute; net_route *fDefaultRoute;
// used for local requests // used for local requests
bool fRequestPrimaryDNS, fRequestSecondaryDNS; bool fRequestPrimaryDNS, fRequestSecondaryDNS;
// for state machine // for state machine
ppp_state fState; ppp_state fState;
vint32 fID; int32 fID;
// counters and timers // counters and timers
int32 fMaxRequest, fMaxTerminate, fMaxNak; int32 fMaxRequest, fMaxTerminate, fMaxNak;
int32 fRequestCounter, fTerminateCounter, fNakCounter; int32 fRequestCounter, fTerminateCounter, fNakCounter;
+32 -23
View File
@@ -5,21 +5,24 @@
#include <KernelExport.h> #include <KernelExport.h>
#include <driver_settings.h> #include <driver_settings.h>
#include <core_funcs.h>
#include <net_module.h>
#include <NetBufferUtilities.h>
#include <net_buffer.h>
#include <net_stack.h>
#include <KPPPDefs.h>
#include <KPPPInterface.h> #include <KPPPInterface.h>
#include <KPPPModule.h> #include <KPPPModule.h>
#include "Protocol.h" #include "Protocol.h"
#define IPCP_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/ipcp"
#define IPCP_MODULE_NAME NETWORK_MODULES_ROOT "ppp/ipcp"
struct protosw *gProto[IPPROTO_MAX];
struct core_module_info *core = NULL;
status_t std_ops(int32 op, ...); status_t std_ops(int32 op, ...);
net_stack_module_info *gStackModule = NULL;
net_buffer_module_info *gBufferModule = NULL;
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// TODO: Remove isascii() (needed for inet_aton()) when our kernel is finished! // TODO: Remove isascii() (needed for inet_aton()) when our kernel is finished!
@@ -28,7 +31,7 @@ extern "C"
int int
isascii(char c) isascii(char c)
{ {
return c & ~0x7f == 0; // If c is a 7 bit value. return ((c & (~0x7f)) == 0); // If c is a 7 bit value.
} }
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -38,22 +41,22 @@ bool
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface, add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
driver_parameter *settings, ppp_module_key_type type) driver_parameter *settings, ppp_module_key_type type)
{ {
if(type != PPP_PROTOCOL_KEY_TYPE) if (type != PPP_PROTOCOL_KEY_TYPE)
return B_ERROR; return B_ERROR;
IPCP *ipcp; IPCP *ipcp;
bool success; bool success;
if(subInterface) { if (subInterface) {
ipcp = new IPCP(*subInterface, settings); ipcp = new IPCP(*subInterface, settings);
success = subInterface->AddProtocol(ipcp); success = subInterface->AddProtocol(ipcp);
} else { } else {
ipcp = new IPCP(mainInterface, settings); ipcp = new IPCP(mainInterface, settings);
success = mainInterface.AddProtocol(ipcp); success = mainInterface.AddProtocol(ipcp);
} }
TRACE("IPCP: add_to(): %s\n", TRACE("IPCP: add_to(): %s\n",
success && ipcp && ipcp->InitCheck() == B_OK ? "OK" : "ERROR"); success && ipcp && ipcp->InitCheck() == B_OK ? "OK" : "ERROR");
return success && ipcp && ipcp->InitCheck() == B_OK; return success && ipcp && ipcp->InitCheck() == B_OK;
} }
@@ -71,24 +74,30 @@ static ppp_module_info ipcp_module = {
_EXPORT _EXPORT
status_t status_t
std_ops(int32 op, ...) std_ops(int32 op, ...)
{ {
switch(op) { switch (op) {
case B_MODULE_INIT: case B_MODULE_INIT:
if(get_module(NET_CORE_MODULE_NAME, (module_info**) &core) != B_OK) if (get_module(NET_STACK_MODULE_NAME,
(module_info**) &gStackModule) != B_OK)
return B_ERROR; return B_ERROR;
memset(gProto, 0, sizeof(struct protosw*) * IPPROTO_MAX); if (get_module(NET_BUFFER_MODULE_NAME,
add_protosw(gProto, NET_LAYER1); (module_info **)&gBufferModule) != B_OK) {
return B_OK; put_module(NET_STACK_MODULE_NAME);
return B_ERROR;
}
return B_OK;
break;
case B_MODULE_UNINIT: case B_MODULE_UNINIT:
put_module(NET_CORE_MODULE_NAME); put_module(NET_BUFFER_MODULE_NAME);
break; put_module(NET_STACK_MODULE_NAME);
break;
default: default:
return B_ERROR; return B_ERROR;
} }
return B_OK; return B_OK;
} }
+3 -9
View File
@@ -1,6 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel network ppp pap ; SubDir HAIKU_TOP src add-ons kernel network ppp pap ;
SetSubDirSupportedPlatformsBeOSCompatible ; SetSubDirSupportedPlatformsBeOSCompatible ;
SubDirC++Flags -fno-rtti ;
if $(TARGET_PLATFORM) != haiku { if $(TARGET_PLATFORM) != haiku {
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
# Unfortunately we get more than we want, namely all POSIX headers. # Unfortunately we get more than we want, namely all POSIX headers.
} }
# for kernel_cpp.h and BLocker UsePrivateKernelHeaders ;
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
UsePrivateHeaders net ; UsePrivateHeaders net ;
UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel ] ;
UsePrivateHeaders [ FDirName kernel util ] ; UsePrivateHeaders [ FDirName kernel util ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
libkernelppp headers ] : true ; libkernelppp headers ] : true ;
{
SubDirC++Flags -fno-rtti ;
}
KernelAddon pap : KernelAddon pap :
pap.cpp pap.cpp
Protocol.cpp Protocol.cpp
@@ -31,5 +25,5 @@ LinkAgainst pap : libkernelppp.a ;
# Installation # Installation
HaikuInstall install-networking HaikuInstall install-networking
: /boot/home/config/add-ons/kernel/obos_network/ppp : /boot/home/config/add-ons/kernel/haiku_network/ppp
: pap ; : pap ;
+169 -145
View File
@@ -9,9 +9,9 @@
#include <cstring> #include <cstring>
#include <netinet/in.h> #include <netinet/in.h>
#include <core_funcs.h>
#include <sys/sockio.h>
#include <net_buffer.h>
#include <sys/sockio.h>
static const bigtime_t kPAPTimeout = 3000000; static const bigtime_t kPAPTimeout = 3000000;
// 3 seconds // 3 seconds
@@ -34,20 +34,28 @@ PAPHandler::PAPHandler(PAP& owner, KPPPInterface& interface)
} }
status_t
PAPHandler::SendingAck(const KPPPConfigurePacket& ack)
{
TRACE("%s::%s: We should activate PAP Protocol here\n", __FILE__, __func__);
return KPPPOptionHandler::SendingAck(ack);
}
status_t status_t
PAPHandler::AddToRequest(KPPPConfigurePacket& request) PAPHandler::AddToRequest(KPPPConfigurePacket& request)
{ {
// only local authenticators send requests to peer // only local authenticators send requests to peer
if(Owner().Side() != PPP_PEER_SIDE) if (Owner().Side() != PPP_PEER_SIDE)
return B_OK; return B_OK;
authentication_item item; authentication_item item;
item.type = kAuthenticationType; item.type = kAuthenticationType;
item.length = sizeof(item); item.length = sizeof(item);
item.protocolNumber = htons(PAP_PROTOCOL); item.protocolNumber = htons(PAP_PROTOCOL);
request.AddItem((ppp_configure_item*) &item); request.AddItem((ppp_configure_item*) &item);
return B_OK; return B_OK;
} }
@@ -57,15 +65,15 @@ PAPHandler::ParseRequest(const KPPPConfigurePacket& request,
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject) int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject)
{ {
// only local authenticators handle requests from peer // only local authenticators handle requests from peer
if(Owner().Side() != PPP_LOCAL_SIDE) if (Owner().Side() != PPP_LOCAL_SIDE)
return B_OK; return B_OK;
// we merely check if the values are correct // we merely check if the values are correct
authentication_item *item = (authentication_item*) request.ItemAt(index); authentication_item *item = (authentication_item*) request.ItemAt(index);
if(item->type != kAuthenticationType if (item->type != kAuthenticationType
|| item->length != 4 || ntohs(item->protocolNumber) != PAP_PROTOCOL) || item->length != 4 || ntohs(item->protocolNumber) != PAP_PROTOCOL)
return B_ERROR; return B_ERROR;
return B_OK; return B_OK;
} }
@@ -92,9 +100,9 @@ PAP::~PAP()
status_t status_t
PAP::InitCheck() const PAP::InitCheck() const
{ {
if(Side() != PPP_LOCAL_SIDE && Side() != PPP_PEER_SIDE) if (Side() != PPP_LOCAL_SIDE && Side() != PPP_PEER_SIDE)
return B_ERROR; return B_ERROR;
return KPPPProtocol::InitCheck(); return KPPPProtocol::InitCheck();
} }
@@ -103,14 +111,14 @@ bool
PAP::Up() PAP::Up()
{ {
TRACE("PAP: Up() state=%d\n", State()); TRACE("PAP: Up() state=%d\n", State());
switch(State()) { switch (State()) {
case INITIAL: case INITIAL:
if(Side() == PPP_LOCAL_SIDE) { if (Side() == PPP_LOCAL_SIDE) {
NewState(REQ_SENT); NewState(REQ_SENT);
InitializeRestartCount(); InitializeRestartCount();
SendRequest(); SendRequest();
} else if(Side() == PPP_PEER_SIDE) { } else if (Side() == PPP_PEER_SIDE) {
NewState(WAITING_FOR_REQ); NewState(WAITING_FOR_REQ);
InitializeRestartCount(); InitializeRestartCount();
fNextTimeout = system_time() + kPAPTimeout; fNextTimeout = system_time() + kPAPTimeout;
@@ -119,11 +127,11 @@ PAP::Up()
return false; return false;
} }
break; break;
default: default:
; ;
} }
return true; return true;
} }
@@ -132,8 +140,8 @@ bool
PAP::Down() PAP::Down()
{ {
TRACE("PAP: Down() state=%d\n", State()); TRACE("PAP: Down() state=%d\n", State());
switch(Interface().Phase()) { switch (Interface().Phase()) {
case PPP_DOWN_PHASE: case PPP_DOWN_PHASE:
// interface finished terminating // interface finished terminating
case PPP_ESTABLISHED_PHASE: case PPP_ESTABLISHED_PHASE:
@@ -141,82 +149,83 @@ PAP::Down()
NewState(INITIAL); NewState(INITIAL);
DownEvent(); DownEvent();
break; break;
/* case PPP_TERMINATION_PHASE: /* case PPP_TERMINATION_PHASE:
// interface is terminating // interface is terminating
break; break;
case PPP_ESTABLISHMENT_PHASE: case PPP_ESTABLISHMENT_PHASE:
// interface is reconfiguring // interface is reconfiguring
break; break;
*/ */
default: default:
; ;
} }
return true; return true;
} }
status_t status_t
PAP::Send(struct mbuf *packet, uint16 protocolNumber) PAP::Send(net_buffer *packet, uint16 protocolNumber)
{ {
// we do not encapsulate PAP packets // we do not encapsulate PAP packets
m_freem(packet); TRACE("PAP: we should not send packet!\n");
if (packet != NULL)
gBufferModule->free(packet);
return B_ERROR; return B_ERROR;
} }
status_t status_t
PAP::Receive(struct mbuf *packet, uint16 protocolNumber) PAP::Receive(net_buffer *packet, uint16 protocolNumber)
{ {
if(!packet) if (!packet)
return B_ERROR; return B_ERROR;
if(protocolNumber != PAP_PROTOCOL) if (protocolNumber != PAP_PROTOCOL)
return PPP_UNHANDLED; return PPP_UNHANDLED;
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*); NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
if (bufferheader.Status() != B_OK)
return B_ERROR;
ppp_lcp_packet &data = bufferheader.Data();
// check if the packet is meant for us: // check if the packet is meant for us:
// only peer authenticators handle requests // only peer authenticators handle requests
if(data->code == PPP_CONFIGURE_REQUEST && Side() != PPP_PEER_SIDE) if (data.code == PPP_CONFIGURE_REQUEST && Side() != PPP_PEER_SIDE)
return PPP_UNHANDLED; return PPP_UNHANDLED;
// only local authenticators handle acks and naks // only local authenticators handle acks and naks
if((data->code == PPP_CONFIGURE_ACK || data->code == PPP_CONFIGURE_NAK) if ((data.code == PPP_CONFIGURE_ACK || data.code == PPP_CONFIGURE_NAK)
&& Side() != PPP_LOCAL_SIDE) && Side() != PPP_LOCAL_SIDE)
return PPP_UNHANDLED; return PPP_UNHANDLED;
// remove padding // remove padding
int32 length = packet->m_len; int32 length = packet->size;
if(packet->m_flags & M_PKTHDR) length -= ntohs(data.length);
length = packet->m_pkthdr.len;
length -= ntohs(data->length); if (ntohs(data.length) < 4)
if(length)
m_adj(packet, -length);
if(ntohs(data->length) < 4)
return B_ERROR; return B_ERROR;
// packet is freed by event methods // packet is freed by event methods
// code values are the same as for LCP (but very reduced) // code values are the same as for LCP (but very reduced)
switch(data->code) { switch (data.code) {
case PPP_CONFIGURE_REQUEST: case PPP_CONFIGURE_REQUEST:
RREvent(packet); RREvent(packet);
break; break;
case PPP_CONFIGURE_ACK: case PPP_CONFIGURE_ACK:
RAEvent(packet); RAEvent(packet);
break; break;
case PPP_CONFIGURE_NAK: case PPP_CONFIGURE_NAK:
RNEvent(packet); RNEvent(packet);
break; break;
default: default:
return PPP_UNHANDLED; return PPP_UNHANDLED;
} }
return B_OK; return B_OK;
} }
@@ -224,19 +233,19 @@ PAP::Receive(struct mbuf *packet, uint16 protocolNumber)
void void
PAP::Pulse() PAP::Pulse()
{ {
if(fNextTimeout == 0 || fNextTimeout > system_time()) if (fNextTimeout == 0 || fNextTimeout > system_time())
return; return;
fNextTimeout = 0; fNextTimeout = 0;
switch(State()) { switch (State()) {
case REQ_SENT: case REQ_SENT:
case WAITING_FOR_REQ: case WAITING_FOR_REQ:
if(fRequestCounter <= 0) if (fRequestCounter <= 0)
TOBadEvent(); TOBadEvent();
else else
TOGoodEvent(); TOGoodEvent();
break; break;
default: default:
; ;
} }
@@ -254,22 +263,22 @@ void
PAP::NewState(pap_state next) PAP::NewState(pap_state next)
{ {
TRACE("PAP: NewState(%d) state=%d\n", next, State()); TRACE("PAP: NewState(%d) state=%d\n", next, State());
// state changes // state changes
if(State() == INITIAL && next != State()) { if (State() == INITIAL && next != State()) {
if(Side() == PPP_LOCAL_SIDE) if (Side() == PPP_LOCAL_SIDE)
Interface().StateMachine().LocalAuthenticationRequested(); Interface().StateMachine().LocalAuthenticationRequested();
else if(Side() == PPP_PEER_SIDE) else if (Side() == PPP_PEER_SIDE)
Interface().StateMachine().PeerAuthenticationRequested(); Interface().StateMachine().PeerAuthenticationRequested();
UpStarted(); UpStarted();
} else if(State() == ACCEPTED && next != State()) } else if (State() == ACCEPTED && next != State())
DownStarted(); DownStarted();
// maybe we do not need the timer anymore // maybe we do not need the timer anymore
if(next == INITIAL || next == ACCEPTED) if (next == INITIAL || next == ACCEPTED)
fNextTimeout = 0; fNextTimeout = 0;
fState = next; fState = next;
} }
@@ -278,16 +287,16 @@ void
PAP::TOGoodEvent() PAP::TOGoodEvent()
{ {
TRACE("PAP: TOGoodEvent() state=%d\n", State()); TRACE("PAP: TOGoodEvent() state=%d\n", State());
switch(State()) { switch (State()) {
case REQ_SENT: case REQ_SENT:
SendRequest(); SendRequest();
break; break;
case WAITING_FOR_REQ: case WAITING_FOR_REQ:
fNextTimeout = system_time() + kPAPTimeout; fNextTimeout = system_time() + kPAPTimeout;
break; break;
default: default:
; ;
} }
@@ -298,21 +307,21 @@ void
PAP::TOBadEvent() PAP::TOBadEvent()
{ {
TRACE("PAP: TOBadEvent() state=%d\n", State()); TRACE("PAP: TOBadEvent() state=%d\n", State());
switch(State()) { switch (State()) {
case REQ_SENT: case REQ_SENT:
case WAITING_FOR_REQ: case WAITING_FOR_REQ:
NewState(INITIAL); NewState(INITIAL);
if(State() == REQ_SENT) if (State() == REQ_SENT)
Interface().StateMachine().LocalAuthenticationDenied( Interface().StateMachine().LocalAuthenticationDenied(
Interface().Username()); Interface().Username());
else else
Interface().StateMachine().PeerAuthenticationDenied( Interface().StateMachine().PeerAuthenticationDenied(
Interface().Username()); Interface().Username());
UpFailedEvent(); UpFailedEvent();
break; break;
default: default:
; ;
} }
@@ -320,27 +329,30 @@ PAP::TOBadEvent()
void void
PAP::RREvent(struct mbuf *packet) PAP::RREvent(net_buffer *packet)
{ {
TRACE("PAP: RREvent() state=%d\n", State()); TRACE("PAP: RREvent() state=%d\n", State());
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*); NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
int32 length = ntohs(request->length); if (bufferheader.Status() != B_OK)
uint8 *data = request->data; return;
ppp_lcp_packet &request = bufferheader.Data();
int32 length = ntohs(request.length);
uint8 *data = request.data;
uint8 *userLength = data; uint8 *userLength = data;
uint8 *passwordLength = data + 1 + data[0]; uint8 *passwordLength = data + 1 + data[0];
// make sure the length values are all okay // make sure the length values are all okay
if(6 + *userLength + *passwordLength > length) { if (6 + *userLength + *passwordLength > length) {
m_freem(packet); gBufferModule->free(packet);
return; return;
} }
char *peerUsername = (char*) userLength + 1, char *peerUsername = (char*) userLength + 1,
*peerPassword = (char*) passwordLength + 1; *peerPassword = (char*) passwordLength + 1;
const char *username = Interface().Username(), *password = Interface().Password(); const char *username = Interface().Username(), *password = Interface().Password();
if(*userLength == strlen(username) && *passwordLength == strlen(password) if (*userLength == strlen(username) && *passwordLength == strlen(password)
&& !strncmp(peerUsername, username, *userLength) && !strncmp(peerUsername, username, *userLength)
&& !strncmp(peerPassword, password, *passwordLength)) { && !strncmp(peerPassword, password, *passwordLength)) {
NewState(ACCEPTED); NewState(ACCEPTED);
@@ -357,60 +369,68 @@ PAP::RREvent(struct mbuf *packet)
void void
PAP::RAEvent(struct mbuf *packet) PAP::RAEvent(net_buffer *packet)
{ {
TRACE("PAP: RAEvent() state=%d\n", State()); TRACE("PAP: RAEvent() state=%d\n", State());
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) { NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
if (bufferheader.Status() != B_OK)
return;
ppp_lcp_packet &lcp_hdr = bufferheader.Data();
if (fRequestID != lcp_hdr.id) {
// this packet is not a reply to our request // this packet is not a reply to our request
// TODO: log this event // TODO: log this event
m_freem(packet); gBufferModule->free(packet);
return; return;
} }
switch(State()) { switch (State()) {
case REQ_SENT: case REQ_SENT:
NewState(ACCEPTED); NewState(ACCEPTED);
Interface().StateMachine().LocalAuthenticationAccepted( Interface().StateMachine().LocalAuthenticationAccepted(
Interface().Username()); Interface().Username());
UpEvent(); UpEvent();
break; break;
default: default:
; ;
} }
m_freem(packet); gBufferModule->free(packet);
} }
void void
PAP::RNEvent(struct mbuf *packet) PAP::RNEvent(net_buffer *packet)
{ {
TRACE("PAP: RNEvent() state=%d\n", State()); TRACE("PAP: RNEvent() state=%d\n", State());
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) { NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
if (bufferheader.Status() != B_OK)
return;
ppp_lcp_packet &lcp_hdr = bufferheader.Data();
if (fRequestID != lcp_hdr.id) {
// this packet is not a reply to our request // this packet is not a reply to our request
// TODO: log this event // TODO: log this event
m_freem(packet); gBufferModule->free(packet);
return; return;
} }
switch(State()) { switch (State()) {
case REQ_SENT: case REQ_SENT:
NewState(INITIAL); NewState(INITIAL);
Interface().StateMachine().LocalAuthenticationDenied( Interface().StateMachine().LocalAuthenticationDenied(
Interface().Username()); Interface().Username());
UpFailedEvent(); UpFailedEvent();
break; break;
default: default:
; ;
} }
m_freem(packet); gBufferModule->free(packet);
} }
@@ -425,72 +445,76 @@ bool
PAP::SendRequest() PAP::SendRequest()
{ {
TRACE("PAP: SendRequest() state=%d\n", State()); TRACE("PAP: SendRequest() state=%d\n", State());
--fRequestCounter; --fRequestCounter;
fNextTimeout = system_time() + kPAPTimeout; fNextTimeout = system_time() + kPAPTimeout;
struct mbuf *packet = m_gethdr(MT_DATA); net_buffer *packet = gBufferModule->create(256);
if(!packet) if (!packet)
return false; return false;
ppp_lcp_packet *request;
gBufferModule->append_size(packet, 1492, (void **)&request);
const char *username = Interface().Username(), *password = Interface().Password(); const char *username = Interface().Username(), *password = Interface().Password();
uint16 packcketLenth = 6 + strlen(username) + strlen(password);
packet->m_pkthdr.len = packet->m_len = 6 + strlen(username) + strlen(password); // 6 : lcp header 4 byte + username length 1 byte + password length 1 byte
// reserve some space for overhead (we are lazy and reserve too much)
packet->m_data += Interface().PacketOverhead();
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
request->code = PPP_CONFIGURE_REQUEST; request->code = PPP_CONFIGURE_REQUEST;
request->id = fRequestID = NextID(); request->id = fRequestID = NextID();
request->length = htons(packet->m_len); request->length = htons(packcketLenth);
uint8 *data = request->data; uint8 *data = request->data;
data[0] = strlen(username); data[0] = strlen(username);
memcpy(data + 1, username, strlen(username)); memcpy(data + 1, username, strlen(username));
data[1 + data[0]] = strlen(password); data[1 + data[0]] = strlen(password);
memcpy(data + 2 + data[0], password, strlen(password)); memcpy(data + 2 + data[0], password, strlen(password));
gBufferModule->trim(packet, packcketLenth);
return Interface().Send(packet, PAP_PROTOCOL) == B_OK; return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
} }
bool bool
PAP::SendAck(struct mbuf *packet) PAP::SendAck(net_buffer *packet)
{ {
TRACE("PAP: SendAck() state=%d\n", State()); TRACE("PAP: SendAck() state=%d\n", State());
if(!packet) if (!packet)
return false; return false;
ppp_lcp_packet *ack = mtod(packet, ppp_lcp_packet*); NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
ack->code = PPP_CONFIGURE_ACK; if (bufferheader.Status() != B_OK)
packet->m_len = 5; return false;
if(packet->m_flags & M_PKTHDR) ppp_lcp_packet &ack = bufferheader.Data();
packet->m_pkthdr.len = 5;
ack->length = htons(packet->m_len); ack.code = PPP_CONFIGURE_ACK;
ack.length = htons(5);
ack->data[0] = 0; ack.data[0] = 0;
gBufferModule->trim(packet, 5);
bufferheader.Sync();
return Interface().Send(packet, PAP_PROTOCOL) == B_OK; return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
} }
bool bool
PAP::SendNak(struct mbuf *packet) PAP::SendNak(net_buffer *packet)
{ {
TRACE("PAP: SendNak() state=%d\n", State()); ERROR("PAP: SendNak() state=%d\n", State());
if(!packet) if (!packet)
return false; return false;
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*); NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
nak->code = PPP_CONFIGURE_NAK; if (bufferheader.Status() != B_OK)
packet->m_len = 5; return false;
if(packet->m_flags & M_PKTHDR) ppp_lcp_packet &nak = bufferheader.Data();
packet->m_pkthdr.len = 5; nak.code = PPP_CONFIGURE_NAK;
nak->length = htons(packet->m_len); nak.length = htons(5);
nak.data[0] = 0;
nak->data[0] = 0; gBufferModule->trim(packet, 5);
return Interface().Send(packet, PAP_PROTOCOL) == B_OK; return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
} }
+18 -17
View File
@@ -31,11 +31,12 @@ class PAP;
class PAPHandler : public KPPPOptionHandler { class PAPHandler : public KPPPOptionHandler {
public: public:
PAPHandler(PAP& owner, KPPPInterface& interface); PAPHandler(PAP& owner, KPPPInterface& interface);
PAP& Owner() const PAP& Owner() const
{ return fOwner; } { return fOwner; }
virtual status_t AddToRequest(KPPPConfigurePacket& request); virtual status_t AddToRequest(KPPPConfigurePacket& request);
virtual status_t SendingAck(const KPPPConfigurePacket&);
virtual status_t ParseRequest(const KPPPConfigurePacket& request, virtual status_t ParseRequest(const KPPPConfigurePacket& request,
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject); int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject);
@@ -48,17 +49,17 @@ class PAP : public KPPPProtocol {
public: public:
PAP(KPPPInterface& interface, driver_parameter *settings); PAP(KPPPInterface& interface, driver_parameter *settings);
virtual ~PAP(); virtual ~PAP();
virtual status_t InitCheck() const; virtual status_t InitCheck() const;
pap_state State() const pap_state State() const
{ return fState; } { return fState; }
virtual bool Up(); virtual bool Up();
virtual bool Down(); virtual bool Down();
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber); virtual status_t Send(net_buffer *packet, uint16 protocolNumber);
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
virtual void Pulse(); virtual void Pulse();
private: private:
@@ -66,28 +67,28 @@ class PAP : public KPPPProtocol {
void NewState(pap_state next); void NewState(pap_state next);
uint8 NextID(); uint8 NextID();
// return the next id for PAP packets // return the next id for PAP packets
// events // events
void TOGoodEvent(); void TOGoodEvent();
void TOBadEvent(); void TOBadEvent();
void RREvent(struct mbuf *packet); void RREvent(net_buffer *packet);
void RAEvent(struct mbuf *packet); void RAEvent(net_buffer *packet);
void RNEvent(struct mbuf *packet); void RNEvent(net_buffer *packet);
// actions // actions
void ReportUpFailedEvent(); void ReportUpFailedEvent();
void ReportUpEvent(); void ReportUpEvent();
void ReportDownEvent(); void ReportDownEvent();
void InitializeRestartCount(); void InitializeRestartCount();
bool SendRequest(); bool SendRequest();
bool SendAck(struct mbuf *packet); bool SendAck(net_buffer *packet);
bool SendNak(struct mbuf *packet); bool SendNak(net_buffer *packet);
private: private:
// for state machine // for state machine
pap_state fState; pap_state fState;
vint32 fID; int32 fID;
// counters and timers // counters and timers
int32 fMaxRequest; int32 fMaxRequest;
int32 fRequestCounter; int32 fRequestCounter;
+25 -20
View File
@@ -5,42 +5,41 @@
#include <KernelExport.h> #include <KernelExport.h>
#include <driver_settings.h> #include <driver_settings.h>
#include <core_funcs.h>
#include <net_module.h> #include <net_buffer.h>
#include <net_stack.h>
#include <KPPPInterface.h> #include <KPPPInterface.h>
#include <KPPPModule.h> #include <KPPPModule.h>
#include "Protocol.h" #include "Protocol.h"
#define PAP_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/pap"
#define PAP_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pap" net_stack_module_info *gStackModule = NULL;
net_buffer_module_info *gBufferModule = NULL;
struct core_module_info *core = NULL;
status_t std_ops(int32 op, ...); status_t std_ops(int32 op, ...);
static bool
static
bool
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface, add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
driver_parameter *settings, ppp_module_key_type type) driver_parameter *settings, ppp_module_key_type type)
{ {
if(type != PPP_AUTHENTICATOR_KEY_TYPE) if (type != PPP_AUTHENTICATOR_KEY_TYPE)
return B_ERROR; return B_ERROR;
PAP *pap; PAP *pap;
bool success; bool success;
if(subInterface) { if (subInterface) {
pap = new PAP(*subInterface, settings); pap = new PAP(*subInterface, settings);
success = subInterface->AddProtocol(pap); success = subInterface->AddProtocol(pap);
} else { } else {
pap = new PAP(mainInterface, settings); pap = new PAP(mainInterface, settings);
success = mainInterface.AddProtocol(pap); success = mainInterface.AddProtocol(pap);
} }
TRACE("PAP: add_to(): %s\n", TRACE("PAP: add_to(): %s\n",
success && pap && pap->InitCheck() == B_OK ? "OK" : "ERROR"); success && pap && pap->InitCheck() == B_OK ? "OK" : "ERROR");
return success && pap && pap->InitCheck() == B_OK; return success && pap && pap->InitCheck() == B_OK;
} }
@@ -58,22 +57,28 @@ static ppp_module_info pap_module = {
_EXPORT _EXPORT
status_t status_t
std_ops(int32 op, ...) std_ops(int32 op, ...)
{ {
switch(op) { switch (op) {
case B_MODULE_INIT: case B_MODULE_INIT:
if(get_module(NET_CORE_MODULE_NAME, (module_info**) &core) != B_OK) if (get_module(NET_STACK_MODULE_NAME, (module_info**) &gStackModule) != B_OK)
return B_ERROR; return B_ERROR;
if (get_module(NET_BUFFER_MODULE_NAME,
(module_info **)&gBufferModule) != B_OK) {
put_module(NET_STACK_MODULE_NAME);
return B_ERROR;
}
return B_OK; return B_OK;
case B_MODULE_UNINIT: case B_MODULE_UNINIT:
put_module(NET_CORE_MODULE_NAME); put_module(NET_BUFFER_MODULE_NAME);
put_module(NET_STACK_MODULE_NAME);
break; break;
default: default:
return B_ERROR; return B_ERROR;
} }
return B_OK; return B_OK;
} }
@@ -0,0 +1,28 @@
SubDir HAIKU_TOP src add-ons kernel network ppp ppp ;
SetSubDirSupportedPlatformsBeOSCompatible ;
SubDirC++Flags -fno-rtti ;
if $(TARGET_PLATFORM) != haiku {
UseHeaders [ FStandardOSHeaders ] : true ;
# Needed for <support/Errors.h> and maybe other stuff.
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
# We need the public network headers also when not compiling for Haiku.
# Unfortunately we get more than we want, namely all POSIX headers.
}
UsePrivateKernelHeaders ;
UsePrivateHeaders net ;
UsePrivateHeaders [ FDirName kernel util ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
libkernelppp headers ] : true ;
KernelAddon ppp :
ppp.cpp
;
# Installation
HaikuInstall install-networking :
/boot/home/config/add-ons/kernel/network/ppp
: ppp ;
+388
View File
@@ -0,0 +1,388 @@
/*
* Copyright 2014, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Lin Longzhou, [email protected]
*/
#include <errno.h>
#include <stdlib.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>
#include <new>
#include <ethernet.h>
#include <ether_driver.h>
#include <net_buffer.h>
#include <net_datalink_protocol.h>
#include <NetBufferUtilities.h>
#include <net_stack.h>
#include <KernelExport.h>
#include <KPPPManager.h>
#include <ppp_device.h>
#define PPP_HEADER_LENGTH (8 + ETHER_HEADER_LENGTH)
net_buffer* create_buffer_for_frame(uint8 *frame, uint16 frame_size);
static const bigtime_t kLinkCheckInterval = 1000000;
// 1 second
net_buffer_module_info *gBufferModule;
ppp_interface_module_info* gPPPInterfaceModule;
static net_stack_module_info *sStackModule;
static mutex sListLock;
static DoublyLinkedList<ppp_device> sCheckList;
static sem_id sLinkChangeSemaphore;
static thread_id sLinkCheckerThread;
// #pragma mark -
//
status_t
ppp_init(const char *name, net_device **_device)
{
// ppp device
dprintf("%s: entering!\n", __func__);
if (strncmp(name, "ppp", 3)) {
dprintf("[%s] not ppp device\n", name);
return B_BAD_VALUE;
}
dprintf("[%s] is ppp device\n", name);
status_t status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
if (status < B_OK)
return status;
// ppp_device *device = new (std::nothrow) ppp_device;
ppp_interface_id idInterface = gPPPInterfaceModule->CreateInterfaceWithName(name, 0);
KPPPInterface * pppInterface = gPPPInterfaceModule->GetInterface(idInterface);
if (idInterface <= 0 || pppInterface == NULL) {
if (idInterface <= 0)
dprintf("%s: idInterface:%ld\n", __func__, idInterface);
else
dprintf("%s: pppInterface == NULL %ld\n", __func__, idInterface);
put_module(NET_BUFFER_MODULE_NAME);
return B_NO_MEMORY;
}
// Ifnet available until interface up phase
ppp_device *device = (ppp_device *)pppInterface->Ifnet();
if (device == NULL) {
dprintf("%s: can not get ppp_device\n", __func__);
put_module(NET_BUFFER_MODULE_NAME);
return B_NO_MEMORY;
}
strcpy(device->name, name);
device->flags = (IFF_BROADCAST | IFF_LINK) & (~IFF_UP);
device->type = IFT_PPP;
device->mtu = 1492;
device->frame_size = 1500;
device->media = IFM_ACTIVE | IFM_ETHER;
device->header_length = PPP_HEADER_LENGTH;
status =sStackModule->init_fifo(&(device->ppp_fifo), "ppp_fifo", 10 * 1500);
// 10 ppp packet at most
if (status < B_OK)
return(status);
TRACE("[%s] finish\n", "allocate ppp_device");
*_device = device;
return B_OK;
}
status_t
ppp_uninit(net_device *device)
{
dprintf("%s: uninit ppp\n", __func__);
ppp_device *ppp_dev=(ppp_device *)device;
sStackModule->uninit_fifo(&(ppp_dev->ppp_fifo));
put_module(NET_BUFFER_MODULE_NAME);
// delete ppp_dev->KPPP_Interface;
delete ppp_dev;
return B_OK;
}
status_t
ppp_up(net_device *_device)
{
dprintf("ppp_up\n");
ppp_device *device = (ppp_device *)_device;
if (device->KPPP_Interface == NULL) {
dprintf("%s: warning! can not find pppinterface KPPP_Interface\n", __func__);
return B_ERROR;
}
if (device->KPPP_Interface->Up() != true) {
dprintf("%s: warning! KPPP_Interface->Up() failure\n", __func__);
return B_ERROR;
}
device->mtu = device->frame_size - device->header_length;
// s_pppoe_dev = device;
dprintf("%s: congratulations! Find pppinterface (device->KPPP_Interface)\n", __func__);
return B_OK;
}
void
ppp_down(net_device *_device)
{
dprintf("%s\n", __func__);
ppp_device *device = (ppp_device *)_device;
device->KPPP_Interface->Down();
MutexLocker _(sListLock);
// if the device is still part of the list, remove it
if (device->GetDoublyLinkedListLink()->next != NULL
|| device->GetDoublyLinkedListLink()->previous != NULL
|| device == sCheckList.Head())
sCheckList.Remove(device);
// device->KPPP_Interface = NULL;
return;
}
status_t
ppp_control(net_device *_device, int32 op, void *argument,
size_t length)
{
TRACE("%s %ld\n", __func__, op);
ppp_device *device = (ppp_device *)_device;
if (device->KPPP_Interface == NULL) {
dprintf("%s: can not find KPPP_Interface for ppp\n", __func__);
return B_OK;
}
return device->KPPP_Interface->Control(op, argument, length);
return B_OK;
}
status_t
ppp_send_data(net_device *_device, net_buffer *buffer)
{
TRACE("%s\n", __func__);
ppp_device *device = (ppp_device *)_device;
if (buffer->size > device->frame_size || buffer->size < device->header_length) {
device->stats.send.errors++;
dprintf("sorry! fail send ppp packet, size wrong!\n");
return B_BAD_VALUE;
}
if (device->KPPP_Interface == NULL) {
device->stats.send.errors++;
dprintf("Fail send ppp packet, no eth for ppp!\n");
return B_BAD_VALUE;
}
size_t net_buffer_size = buffer->size;
// store buffer->size in case buffer freed in KPPP_Interface->Send
status_t status = device->KPPP_Interface->Send(buffer, 0x0021); // IP_PROTOCOL 0x0021
if (status != B_OK) {
device->stats.send.errors++;
dprintf("KPPP_Interface->Send(buffer, 0x0021 IP) fail\n");
return B_BAD_VALUE;
}
device->stats.send.packets++;
device->stats.send.bytes += net_buffer_size;
return B_OK;
}
status_t
ppp_receive_data(net_device *_device, net_buffer **_buffer)
{
TRACE("%s\n", __func__);
ppp_device *device = (ppp_device *)_device;
if (device->KPPP_Interface == NULL)
return B_FILE_ERROR;
TRACE("%s: trying fifo_dequeue_buffer\n", __func__);
status_t status = sStackModule->fifo_dequeue_buffer(&(device->ppp_fifo), 0, 10000000, _buffer);
if (status < B_OK) {
TRACE("sorry! can not fifo_dequeue_buffer!\n");
return status;
}
// (*_buffer)->interface_address = NULL; // strange need to put here
device->stats.receive.bytes += (*_buffer)->size;
device->stats.receive.packets++;
return B_OK;
}
status_t
ppp_set_mtu(net_device *_device, size_t mtu)
{
ppp_device *device = (ppp_device *)_device;
if (mtu > device->frame_size - ETHER_HEADER_LENGTH - 8
|| mtu <= ETHER_HEADER_LENGTH + 8 + 10)
return B_BAD_VALUE;
device->mtu = mtu;
return B_OK;
}
status_t
ppp_set_promiscuous(net_device *_device, bool promiscuous)
{
return B_NOT_SUPPORTED;
}
status_t
ppp_set_media(net_device *device, uint32 media)
{
return B_NOT_SUPPORTED;
}
status_t
ppp_add_multicast(struct net_device *_device, const sockaddr *_address)
{
// ppp_device *device = (ppp_device *)_device;
if (_address->sa_family != AF_LINK)
return B_BAD_VALUE;
const sockaddr_dl *address = (const sockaddr_dl *)_address;
if (address->sdl_type != IFT_ETHER)
return B_BAD_VALUE;
return B_NOT_SUPPORTED;
}
status_t
ppp_remove_multicast(struct net_device *_device, const sockaddr *_address)
{
// ppp_device *device = (ppp_device *)_device;
if (_address->sa_family != AF_LINK)
return B_BAD_VALUE;
const sockaddr_dl *address = (const sockaddr_dl *)_address;
if (address->sdl_type != IFT_ETHER)
return B_BAD_VALUE;
return B_NOT_SUPPORTED;
}
static status_t
ppp_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
{
status_t status = get_module(NET_STACK_MODULE_NAME,
(module_info **)&sStackModule);
if (status < B_OK)
return status;
status = get_module(PPP_INTERFACE_MODULE_NAME,
(module_info**)&gPPPInterfaceModule);
if (status < B_OK) {
put_module(NET_STACK_MODULE_NAME);
return status;
}
new (&sCheckList) DoublyLinkedList<ppp_device>;
// static C++ objects are not initialized in the module startup
sLinkCheckerThread = -1;
sLinkChangeSemaphore = create_sem(0, "ppp link change");
if (sLinkChangeSemaphore < B_OK) {
put_module(PPP_INTERFACE_MODULE_NAME);
put_module(NET_STACK_MODULE_NAME);
return sLinkChangeSemaphore;
}
mutex_init(&sListLock, "ppp devices");
return B_OK;
}
case B_MODULE_UNINIT:
{
delete_sem(sLinkChangeSemaphore);
status_t status;
wait_for_thread(sLinkCheckerThread, &status);
mutex_destroy(&sListLock);
put_module(PPP_INTERFACE_MODULE_NAME);
put_module(NET_STACK_MODULE_NAME);
return B_OK;
}
default:
return B_ERROR;
}
}
net_device_module_info spppModule = {
{
"network/devices/ppp/v1",
0,
ppp_std_ops
},
ppp_init,
ppp_uninit,
ppp_up,
ppp_down,
ppp_control,
ppp_send_data,
ppp_receive_data,
ppp_set_mtu,
ppp_set_promiscuous,
ppp_set_media,
ppp_add_multicast,
ppp_remove_multicast,
};
module_info *modules[] = {
(module_info *)&spppModule,
NULL
};
@@ -0,0 +1,26 @@
SubDir HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
SetSubDirSupportedPlatformsBeOSCompatible ;
SubDirC++Flags -fno-rtti ;
if $(TARGET_PLATFORM) != haiku {
UseHeaders [ FStandardOSHeaders ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
# We need the public network headers also when not compiling for Haiku.
# Unfortunately we get more than we want, namely all POSIX headers.
}
UsePrivateKernelHeaders ;
UsePrivateHeaders kernel net ;
UsePrivateHeaders [ FDirName kernel util ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
libkernelppp headers ] : true ;
KernelAddon ppp_frame :
ppp_frame.cpp
;
# Installation
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/ppp
: ppp_frame ;
@@ -0,0 +1,265 @@
/*
* Copyright 2014, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Lin Longzhou, [email protected]
*/
#include <ethernet.h>
#include <net/if_types.h>
#include <net_datalink_protocol.h>
#include <net_datalink.h>
#include <KernelExport.h>
#include <new>
#include <PPPControl.h>
#include <ppp_device.h>
struct ppp_frame_protocol : net_datalink_protocol {
};
static net_stack_module_info *sStackModule;
status_t
ppp_deframe(net_device* device, net_buffer* buffer)
{
TRACE("%s: buffer type:%lx\n", __func__, buffer->type);
return B_OK;
}
// #pragma mark -
status_t
ppp_frame_init(struct net_interface* interface, net_domain* domain,
net_datalink_protocol** _protocol)
{
// We only support a single type!
dprintf("in function: %s::%s\n", __FILE__, __func__);
if (interface->device->type != IFT_PPP)
return B_BAD_TYPE;
ppp_frame_protocol* protocol;
status_t status = sStackModule->register_device_deframer(interface->device,
&ppp_deframe);
if (status != B_OK)
return status;
status = sStackModule->register_domain_device_handler(
interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE), domain);
if (status != B_OK)
return status;
status = sStackModule->register_domain_device_handler(
interface->device, B_NET_FRAME_TYPE_IPV4, domain);
if (status != B_OK)
return status;
// Locally received buffers don't need a domain device handler, as the
// buffer reception is handled internally.
protocol = new(std::nothrow) ppp_frame_protocol;
if (protocol == NULL) {
sStackModule->unregister_device_deframer(interface->device);
return B_NO_MEMORY;
}
*_protocol = protocol;
return B_OK;
}
status_t
ppp_frame_uninit(net_datalink_protocol* protocol)
{
sStackModule->unregister_device_deframer(protocol->interface->device);
sStackModule->unregister_device_handler(protocol->interface->device, 0);
delete protocol;
TRACE("%s\n", __func__);
return B_OK;
}
status_t
ppp_frame_send_data(net_datalink_protocol* protocol, net_buffer* buffer)
{
TRACE("%s: next module is %s\n", __func__, protocol->next->module->info.name);
return protocol->next->module->send_data(protocol->next, buffer);
}
status_t
ppp_frame_up(net_datalink_protocol* protocol)
{
dprintf("in function: %s\n", __func__);
return protocol->next->module->interface_up(protocol->next);
}
void
ppp_frame_down(net_datalink_protocol* protocol)
{
dprintf("%s::%s: entry\n", __FILE__, __func__);
protocol->next->module->interface_down(protocol->next);
return;
}
status_t
ppp_frame_change_address(net_datalink_protocol* protocol,
net_interface_address* address, int32 option,
const struct sockaddr* oldAddress, const struct sockaddr* newAddress)
{
TRACE("in function: %s::%s\n", __FILE__, __func__);
return protocol->next->module->change_address(protocol->next, address,
option, oldAddress, newAddress);
}
static status_t
PPP_module_control(int32 option, void* argument, size_t length)
{
// control_net_module_args* args=(control_net_module_args*)argument;
if (option < PPPC_CONTROL_MODULE || option > PPP_CONTROL_OPS_END)
return B_ERROR;
// if (args->name != PPP_INTERFACE_MODULE_NAME)
// return B_ERROR;
switch(option)
{
case PPPC_CREATE_INTERFACE:
// process_CreateInterface(args->data, args->length);
case PPPC_CREATE_INTERFACE_WITH_NAME:
case PPPC_DELETE_INTERFACE:
case PPPC_BRING_INTERFACE_UP:
case PPPC_BRING_INTERFACE_DOWN:
case PPPC_CONTROL_INTERFACE:
case PPPC_GET_INTERFACES:
case PPPC_COUNT_INTERFACES:
case PPPC_FIND_INTERFACE_WITH_SETTINGS:
// interface control
case PPPC_GET_INTERFACE_INFO:
case PPPC_SET_USERNAME:
case PPPC_SET_PASSWORD:
case PPPC_SET_ASK_BEFORE_CONNECTING:
// ppp_up uses this in order to finalize a connection request
case PPPC_SET_MRU:
case PPPC_SET_CONNECT_ON_DEMAND:
case PPPC_SET_AUTO_RECONNECT:
case PPPC_HAS_INTERFACE_SETTINGS:
case PPPC_GET_STATISTICS:
// handler access
case PPPC_CONTROL_DEVICE:
case PPPC_CONTROL_PROTOCOL:
case PPPC_CONTROL_OPTION_HANDLER:
case PPPC_CONTROL_LCP_EXTENSION:
case PPPC_CONTROL_CHILD:
// KPPPDevice
case PPPC_GET_DEVICE_INFO:
// KPPPProtocol
case PPPC_GET_PROTOCOL_INFO:
// Common/mixed ops
case PPPC_ENABLE:
case PPPC_GET_SIMPLE_HANDLER_INFO:
// these two control ops use the ppp_report_request structure
case PPPC_ENABLE_REPORTS:
case PPPC_DISABLE_REPORTS:
case PPP_CONTROL_OPS_END:
case PPPC_CONTROL_MODULE:
default:
return B_ERROR;
}
}
static status_t
ppp_frame_control(net_datalink_protocol* protocol, int32 option,
void* argument, size_t length)
{
TRACE("%s: option:%ld\n", __func__, option);
if (option >= PPPC_CONTROL_MODULE && option <=PPP_CONTROL_OPS_END)
{
status_t status =PPP_module_control(option, argument, length);
// gPPPInterfaceModule->ControlInterface(1, option, argument, length);
return status;
}
return protocol->next->module->control(protocol->next, option, argument,
length);
}
static status_t
ppp_frame_join_multicast(net_datalink_protocol* protocol,
const sockaddr* address)
{
TRACE("in function: %s\n", __func__);
return protocol->next->module->join_multicast(protocol->next, address);
}
static status_t
ppp_frame_leave_multicast(net_datalink_protocol* protocol,
const sockaddr* address)
{
TRACE("in function: %s\n", __func__);
return protocol->next->module->leave_multicast(protocol->next, address);
}
static status_t
pppoe_frame_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
if (get_module(NET_STACK_MODULE_NAME,
(module_info **)&sStackModule) != B_OK)
return B_ERROR;
return B_OK;
case B_MODULE_UNINIT:
put_module(NET_STACK_MODULE_NAME);
return B_OK;
default:
return B_ERROR;
}
}
static net_datalink_protocol_module_info sPPPFrameModule = {
{
"network/datalink_protocols/ppp_frame/v1",
0,
pppoe_frame_std_ops
},
ppp_frame_init,
ppp_frame_uninit,
ppp_frame_send_data,
ppp_frame_up,
ppp_frame_down,
ppp_frame_change_address,
ppp_frame_control,
ppp_frame_join_multicast,
ppp_frame_leave_multicast,
};
module_info* modules[] = {
(module_info*)&sPPPFrameModule,
NULL
};
@@ -0,0 +1,31 @@
SubDir HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
SetSubDirSupportedPlatformsBeOSCompatible ;
SubDirC++Flags -fno-rtti ;
if $(TARGET_PLATFORM) != haiku {
UseHeaders [ FStandardOSHeaders ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
# We need the public network headers also when not compiling for Haiku.
# Unfortunately we get more than we want, namely all POSIX headers.
}
UsePrivateKernelHeaders ;
# UsePrivateHeaders net ;
UsePrivateHeaders kernel net ;
UsePrivateHeaders [ FDirName kernel ] ;
UsePrivateHeaders [ FDirName kernel util ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
libkernelppp headers ] : true ;
KernelAddon KPPPManager :
KPPPManager.cpp
;
LinkAgainst KPPPManager : libkernelppp.a ;
# Installation
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/ppp
: KPPPManager ;
@@ -0,0 +1,373 @@
/*
* Copyright 2006-2014, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, [email protected]
* Lin Longzhou, [email protected]
*/
#include <net_stack.h>
#include <NetBufferUtilities.h>
#include <KernelExport.h>
#include <lock.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
#include <new>
#include <ppp_device.h>
#include <KPPPManager.h>
struct entry_private : ppp_interface_entry, DoublyLinkedListLinkImpl<entry_private> {
};
static DoublyLinkedList<entry_private> sEntryList;
net_buffer_module_info* gBufferModule = NULL;
net_stack_module_info* gStackModule = NULL;
// static struct net_interface* sinterface;
static mutex sListLock;
static uint32 ppp_interface_count;
// #pragma mark -
static KPPPInterface * GetInterface(ppp_interface_id ID);
static ppp_interface_id
CreateInterface(const driver_settings *settings, ppp_interface_id parentID)
{
MutexLocker _(sListLock); // auto_lock
if (parentID > 0) {
TRACE("Not support Multi_Link yet!\n");
return 0l;
}
if (settings == NULL) {
TRACE("No driver_settings yet!\n");
return 0l;
}
ppp_interface_count++;
if (GetInterface(ppp_interface_count) != NULL)
return 0l;
entry_private* pentry = new (std::nothrow) entry_private;
memset(pentry, 0, sizeof(entry_private));
pentry->accessing = ppp_interface_count;
sEntryList.Add(pentry);
KPPPInterface *device = new (std::nothrow) KPPPInterface(NULL,
pentry, ppp_interface_count, NULL, NULL);
if (device == NULL || pentry == NULL) {
TRACE("device or pentry is NULL\n");
ppp_interface_count--;
return 0l;
}
TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
return ppp_interface_count; // only support 1 ppp connection right now
}
static ppp_interface_id
CreateInterfaceWithName(const char *name, ppp_interface_id parentID)
{
MutexLocker _(sListLock); // auto_lock
if (parentID > 0) {
dprintf("Not support Multi_Link yet!\n");
return(0);
}
if (strncmp(name, "ppp", 3)) {
dprintf("%s is not ppp device!\n", name);
return(0);
}
ppp_interface_count++;
if (GetInterface(ppp_interface_count) != NULL) {
TRACE("PPP Interface already exist!\n");
return 0l;
}
entry_private* pentry = new (std::nothrow) entry_private;
memset(pentry, 0, sizeof(entry_private));
pentry->accessing = ppp_interface_count;
sEntryList.Add(pentry);
KPPPInterface* device = new (std::nothrow) KPPPInterface(name,
pentry, ppp_interface_count, NULL, NULL);
if (device == NULL || pentry == NULL) {
TRACE("can not create ppp interface!\n");
ppp_interface_count--;
return 0l;
}
TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
return ppp_interface_count;
}
static bool
DeleteInterface(ppp_interface_id ID)
{
MutexLocker _(sListLock); // auto_lock
DoublyLinkedList<entry_private>::Iterator iterator
= sEntryList.GetIterator();
while (iterator.HasNext()) {
entry_private* pentry = iterator.Next();
if ((ppp_interface_id)pentry->accessing == ID) {
pentry->deleting = true;
return true;
}
}
return false;
}
static bool
RemoveInterface(ppp_interface_id ID)
{
MutexLocker _(sListLock); // auto_lock
if (ID <= 0 || ID > ppp_interface_count)
return false;
DoublyLinkedList<entry_private>::Iterator iterator
= sEntryList.GetIterator();
while (iterator.HasNext()) {
entry_private* pentry = iterator.Next();
if ((ppp_interface_id)pentry->accessing == ID) {
pentry->deleting = true;
break;
}
}
return false;
}
static net_device *
RegisterInterface(ppp_interface_id ID)
{
// MutexLocker _(sListLock); // auto_lock
entry_private* entry = NULL;
DoublyLinkedList<entry_private>::Iterator iterator
= sEntryList.GetIterator();
while (iterator.HasNext()) {
entry_private* pentry = iterator.Next();
if ((ppp_interface_id)pentry->accessing == ID) {
entry = pentry;
break;
}
}
if (entry == NULL)
return NULL;
ppp_device *device = new (std::nothrow) ppp_device;
if (device == NULL)
return NULL;
memset(device, 0, sizeof(ppp_device));
device->KPPP_Interface = entry->interface;
return device;
}
static KPPPInterface *
GetInterface(ppp_interface_id ID)
{
// MutexLocker _(sListLock); // auto_lock
DoublyLinkedList<entry_private>::Iterator iterator
= sEntryList.GetIterator();
while (iterator.HasNext()) {
entry_private* pentry = iterator.Next();
TRACE("testing interface id:%ld\n", pentry->accessing);
if ((ppp_interface_id)(pentry->accessing) == ID) {
TRACE("get interface id:%ld\n", ID);
return pentry->interface;
}
}
TRACE("can not get interface id:%ld\n", ID);
return NULL;
}
static bool
UnregisterInterface(ppp_interface_id ID)
{
MutexLocker _(sListLock); // auto_lock
if (ID <= 0 || ID > ppp_interface_count)
return false;
return true;
}
static status_t
ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t length)
{
MutexLocker _(sListLock); // auto_lock
if (ID <= 0 || ID > ppp_interface_count)
return B_ERROR;
DoublyLinkedList<entry_private>::Iterator iterator
= sEntryList.GetIterator();
while (iterator.HasNext()) {
entry_private* pentry = iterator.Next();
if ((ppp_interface_id)pentry->accessing == ID)
return B_OK;
}
return B_ERROR;
}
static int32
GetInterfaces(ppp_interface_id *interfaces, int32 count, ppp_interface_filter filter)
{
MutexLocker _(sListLock);
if (count <= 0 || count > (int32)ppp_interface_count)
return(0);
uint32 ppp_count = 0;
DoublyLinkedList<entry_private>::Iterator iterator
= sEntryList.GetIterator();
while (iterator.HasNext()) {
entry_private* pentry = iterator.Next();
interfaces[ppp_count] = pentry->accessing;
ppp_count++;
}
return ppp_count;
}
static int32
CountInterfaces(ppp_interface_filter filter)
{
MutexLocker _(sListLock); // auto_lock
uint32 ppp_count = 0;
DoublyLinkedList<entry_private>::Iterator iterator
= sEntryList.GetIterator();
while (iterator.HasNext()) {
iterator.Next();
ppp_count++;
}
return ppp_count;
}
static void
EnableReports(ppp_report_type type, thread_id thread, int32 flags)
{
MutexLocker _(sListLock); // auto_lock
return; // need more portrait
}
static void
DisableReports(ppp_report_type type, thread_id thread)
{
MutexLocker _(sListLock); // auto_lock
return; // need more portrait
}
static bool
DoesReport(ppp_report_type type, thread_id thread)
{
MutexLocker _(sListLock); // auto_lock
return false; // need more portrait
}
static status_t
KPPPManager_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
mutex_init(&sListLock, "KPPPManager");
new (&sEntryList) DoublyLinkedList<entry_private>;
// static C++ objects are not initialized in the module startup
ppp_interface_count = 0;
if (get_module(NET_STACK_MODULE_NAME, (module_info**)&gStackModule)
!= B_OK)
return B_ERROR;
if (get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule)
!= B_OK) {
put_module(NET_STACK_MODULE_NAME);
return B_ERROR;
}
return B_OK;
case B_MODULE_UNINIT:
mutex_destroy(&sListLock);
put_module(NET_BUFFER_MODULE_NAME);
put_module(NET_STACK_MODULE_NAME);
return B_OK;
default:
return B_ERROR;
}
}
static ppp_interface_module_info sKPPPManagerModule = {
{
PPP_INTERFACE_MODULE_NAME,
0,
KPPPManager_std_ops
},
CreateInterface,
CreateInterfaceWithName,
DeleteInterface,
RemoveInterface,
RegisterInterface,
GetInterface,
UnregisterInterface,
ControlInterface,
GetInterfaces,
CountInterfaces,
EnableReports,
DisableReports,
DoesReport
};
module_info* modules[] = {
(module_info*)&sKPPPManagerModule,
NULL
};
@@ -3,11 +3,12 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <ByteOrder.h>
#include <NetBufferUtilities.h>
#include <net_buffer.h>
#include "DiscoveryPacket.h" #include "DiscoveryPacket.h"
#include <core_funcs.h>
DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID) DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID)
: fCode(code), : fCode(code),
fSessionID(sessionID), fSessionID(sessionID),
@@ -16,18 +17,26 @@ DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID)
} }
DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start) DiscoveryPacket::DiscoveryPacket(net_buffer *packet, uint32 start)
{ {
// decode packet // decode packet
uint8 *data = mtod(packet, uint8*); NetBufferHeaderReader<pppoe_header> bufferheader(packet);
data += start; if (bufferheader.Status() != B_OK) {
pppoe_header *header = (pppoe_header*) data; dprintf("NetBufferHeaderReader create fail\n");
fInitStatus = B_ERROR;
return;
}
pppoe_header &header = bufferheader.Data();
SetCode(header->code); SetCode(header.code);
uint16 length = ntohs(header->length); uint16 length = ntohs(header.length);
if(length > packet->m_len - PPPoE_HEADER_SIZE - start) { if(length > packet->size - PPPoE_HEADER_SIZE) {
dprintf("packet size less than pppoe payload\n");
dprintf("pppoe payload:%d\n", length);
dprintf("PPPoE_HEADER_SIZE:%d\n", PPPoE_HEADER_SIZE);
dprintf("packet->size:%ld\n", packet->size);
fInitStatus = B_ERROR; fInitStatus = B_ERROR;
return; return;
// there are no tags (or one corrupted tag) // there are no tags (or one corrupted tag)
@@ -37,7 +46,7 @@ DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start)
pppoe_tag *tag; pppoe_tag *tag;
while(position <= length - 4) { while(position <= length - 4) {
tag = (pppoe_tag*) (header->data + position); tag = (pppoe_tag*) (header.data + position);
position += ntohs(tag->length) + 4; position += ntohs(tag->length) + 4;
AddTag(ntohs(tag->type), tag->data, ntohs(tag->length)); AddTag(ntohs(tag->type), tag->data, ntohs(tag->length));
@@ -116,13 +125,21 @@ DiscoveryPacket::TagWithType(uint16 type) const
} }
struct mbuf* net_buffer*
DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve) DiscoveryPacket::ToNetBuffer(uint32 MTU)
{ {
struct mbuf *packet = m_gethdr(MT_DATA); net_buffer *packet = gBufferModule->create(256);
packet->m_data += reserve; if (packet == NULL) {
dprintf("create buffer failure\n");
pppoe_header *header = mtod(packet, pppoe_header*); return NULL;
}
pppoe_header *header ;
status_t status = gBufferModule->append_size(packet, 1492, (void **)&header);
if (status != B_OK) {
dprintf("append size failure\n");
return NULL;
}
header->version = PPPoE_VERSION; header->version = PPPoE_VERSION;
header->type = PPPoE_TYPE; header->type = PPPoE_TYPE;
@@ -137,7 +154,7 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
// make sure we have enough space left // make sure we have enough space left
if(MTU - length < tag->length) { if(MTU - length < tag->length) {
m_freem(packet); gBufferModule->free(packet);
return NULL; return NULL;
} }
@@ -150,7 +167,11 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
} }
header->length = htons(length); header->length = htons(length);
packet->m_pkthdr.len = packet->m_len = length + PPPoE_HEADER_SIZE; status = gBufferModule->trim(packet, length + PPPoE_HEADER_SIZE);
if (status != B_OK) {
dprintf("trim buffer failure\n");
return NULL;
}
return packet; return packet;
} }
@@ -10,6 +10,7 @@
#include <TemplateList.h> #include <TemplateList.h>
#define ETHER_HDR_LEN 14
enum PPPoE_TAG_TYPE { enum PPPoE_TAG_TYPE {
END_OF_LIST = 0x0000, END_OF_LIST = 0x0000,
@@ -37,13 +38,13 @@ typedef struct pppoe_tag {
uint16 type; uint16 type;
uint16 length; uint16 length;
uint8 data[0]; uint8 data[0];
}; } pppoe_tag;
class DiscoveryPacket { class DiscoveryPacket {
public: public:
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000); DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
DiscoveryPacket(struct mbuf *packet, uint32 start = 0); DiscoveryPacket(net_buffer *packet, uint32 start = 0);
~DiscoveryPacket(); ~DiscoveryPacket();
status_t InitCheck() const status_t InitCheck() const
@@ -66,8 +67,8 @@ class DiscoveryPacket {
pppoe_tag *TagAt(int32 index) const; pppoe_tag *TagAt(int32 index) const;
pppoe_tag *TagWithType(uint16 type) const; pppoe_tag *TagWithType(uint16 type) const;
struct mbuf *ToMbuf(uint32 MTU, uint32 reserve = ETHER_HDR_LEN); net_buffer *ToNetBuffer(uint32 MTU);
// the user is responsible for freeing the mbuf // the user is responsible for freeing the net_buffer
private: private:
uint8 fCode; uint8 fCode;
+3 -9
View File
@@ -1,6 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel network ppp pppoe ; SubDir HAIKU_TOP src add-ons kernel network ppp pppoe ;
SetSubDirSupportedPlatformsBeOSCompatible ; SetSubDirSupportedPlatformsBeOSCompatible ;
SubDirC++Flags -fno-rtti ;
if $(TARGET_PLATFORM) != haiku { if $(TARGET_PLATFORM) != haiku {
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
# Unfortunately we get more than we want, namely all POSIX headers. # Unfortunately we get more than we want, namely all POSIX headers.
} }
# for kernel_cpp.h and BLocker UsePrivateKernelHeaders ;
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
UsePrivateHeaders net ; UsePrivateHeaders net ;
UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel ] ;
UsePrivateHeaders [ FDirName kernel util ] ; UsePrivateHeaders [ FDirName kernel util ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
libkernelppp headers ] : true ; libkernelppp headers ] : true ;
{
SubDirC++Flags -fno-rtti ;
}
KernelAddon pppoe : KernelAddon pppoe :
pppoe.cpp pppoe.cpp
PPPoEDevice.cpp PPPoEDevice.cpp
@@ -32,5 +26,5 @@ LinkAgainst pppoe : libkernelppp.a ;
# Installation # Installation
HaikuInstall install-networking HaikuInstall install-networking
: /boot/home/config/add-ons/kernel/obos_network/ppp : /boot/home/config/add-ons/kernel/haiku/ppp
: pppoe ; : pppoe ;
+8 -3
View File
@@ -8,10 +8,15 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#include <net/if.h> #include <net/if.h>
#include <netinet/if_ether.h>
#include <ethernet.h>
#include <ether_driver.h>
#include <net_stack.h>
class PPPoEDevice; class PPPoEDevice;
#define B_NET_FRAME_TYPE_PPPOE B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE)
#define B_NET_FRAME_TYPE_PPPOE_DISCOVERY B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE_DISCOVERY)
#define PPPoE_QUERY_REPORT_SIZE 2048 #define PPPoE_QUERY_REPORT_SIZE 2048
#define PPPoE_QUERY_REPORT 'PoEQ' #define PPPoE_QUERY_REPORT 'PoEQ'
@@ -60,14 +65,14 @@ typedef struct complete_pppoe_header {
// defined in pppoe.cpp // defined in pppoe.cpp
extern ifnet *FindPPPoEInterface(const char *name); extern net_device *FindPPPoEInterface(const char *name);
extern uint32 NewHostUniq(); extern uint32 NewHostUniq();
extern void add_device(PPPoEDevice *device); extern void add_device(PPPoEDevice *device);
extern void remove_device(PPPoEDevice *device); extern void remove_device(PPPoEDevice *device);
#if DEBUG #if DEBUG
// defined in PPPoEDevice.cpp // defined in PPPoEDevice.cpp
extern void dump_packet(struct mbuf *packet); extern void dump_packet(net_buffer *packet);
#endif // DEBUG #endif // DEBUG
@@ -3,41 +3,57 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <cstdlib>
#include <ByteOrder.h>
#include <net/if_dl.h>
#include <net_stack.h>
#include <ethernet.h>
#include <ether_driver.h>
#include "PPPoEDevice.h" #include "PPPoEDevice.h"
#include "DiscoveryPacket.h" #include "DiscoveryPacket.h"
#include <core_funcs.h>
#include <cstdlib>
// from libkernelppp // from libkernelppp
#include <settings_tools.h> #include <settings_tools.h>
extern net_stack_module_info *gStackModule;
extern net_buffer_module_info *gBufferModule;
extern status_t
pppoe_input(void *cookie, net_device *_device, net_buffer *packet);
#if DEBUG #if DEBUG
static char sDigits[] = "0123456789ABCDEF"; static char sDigits[] = "0123456789ABCDEF";
void void
dump_packet(struct mbuf *packet) dump_packet(net_buffer *packet)
{ {
if(!packet) if (!packet)
return; return;
uint8 *data = mtod(packet, uint8*); BufferHeaderReader<uint8> bufferheader(packet);
if (bufferheader.Status() != B_OK)
return;
uint8 &buffer = bufferheader.Data();
uint8 *data = &buffer;
uint8 buffer[33]; uint8 buffer[33];
uint8 bufferIndex = 0; uint8 bufferIndex = 0;
TRACE("Dumping packet;len=%ld;pkthdr.len=%d\n", packet->m_len, TRACE("Dumping packet;len=%ld;pkthdr.len=%d\n", packet->m_len,
packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : -1); packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : -1);
for(uint32 index = 0; index < packet->m_len; index++) { for (uint32 index = 0; index < packet->m_len; index++) {
buffer[bufferIndex++] = sDigits[data[index] >> 4]; buffer[bufferIndex++] = sDigits[data[index] >> 4];
buffer[bufferIndex++] = sDigits[data[index] & 0x0F]; buffer[bufferIndex++] = sDigits[data[index] & 0x0F];
if(bufferIndex == 32 || index == packet->m_len - 1) { if (bufferIndex == 32 || index == packet->m_len - 1) {
buffer[bufferIndex] = 0; buffer[bufferIndex] = 0;
TRACE("%s\n", buffer); TRACE("%s\n", buffer);
bufferIndex = 0; bufferIndex = 0;
} }
} }
} }
#endif #endif
@@ -54,30 +70,39 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
{ {
#if DEBUG #if DEBUG
TRACE("PPPoEDevice: Constructor\n"); TRACE("PPPoEDevice: Constructor\n");
if(!settings || !settings->parameters) if (!settings || !settings->parameters)
TRACE("PPPoEDevice::ctor: No settings!\n"); TRACE("PPPoEDevice::ctor: No settings!\n");
#endif #endif
interface.SetPFCOptions(PPP_ALLOW_PFC); interface.SetPFCOptions(PPP_ALLOW_PFC);
// we do not want to fail just because the other side requests PFC // we do not want to fail just because the other side requests PFC
memset(fPeer, 0xFF, sizeof(fPeer)); memset(fPeer, 0xFF, sizeof(fPeer));
SetMTU(1494); SetMTU(1494);
// MTU size does not contain PPP header // MTU size does not contain PPP header
if (!settings)
dprintf("%s::%s: settings is NULL\n", __FILE__, __func__);
// find ethernet device // find ethernet device
const char *interfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings); finterfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings);
if(!interfaceName) TRACE("%s::%s: finterfaceName is %s\n", __FILE__, __func__,
return; finterfaceName ? finterfaceName : "NULL");
fACName = get_parameter_value(PPPoE_AC_NAME_KEY, settings); fACName = get_parameter_value(PPPoE_AC_NAME_KEY, settings);
TRACE("fACName is %s\n", fACName ? fACName : "NULL");
fServiceName = get_parameter_value(PPPoE_SERVICE_NAME_KEY, settings); fServiceName = get_parameter_value(PPPoE_SERVICE_NAME_KEY, settings);
TRACE("fServiceName is %s\n", fServiceName ? fServiceName : "NULL");
fEthernetIfnet = FindPPPoEInterface(interfaceName);
// fEthernetIfnet = FindPPPoEInterface(interfaceName);
#if DEBUG #if DEBUG
if(!fEthernetIfnet) if (!fEthernetIfnet)
TRACE("PPPoEDevice::ctor: could not find ethernet interface\n"); TRACE("PPPoEDevice::ctor: could not find ethernet interface\n");
else
TRACE("%s::%s: Find Ethernet device", __FILE__, __func__);
#endif #endif
} }
@@ -85,8 +110,10 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
status_t status_t
PPPoEDevice::InitCheck() const PPPoEDevice::InitCheck() const
{ {
return EthernetIfnet() && EthernetIfnet()->output if (KPPPDevice::InitCheck() != B_OK)
&& KPPPDevice::InitCheck() == B_OK ? B_OK : B_ERROR; dprintf("%s::%s: KPPPDevice::InitCheck() has error\n", __FILE__, __func__);
return KPPPDevice::InitCheck() == B_OK ? B_OK : B_ERROR;
} }
@@ -94,72 +121,103 @@ bool
PPPoEDevice::Up() PPPoEDevice::Up()
{ {
TRACE("PPPoEDevice: Up()\n"); TRACE("PPPoEDevice: Up()\n");
if(InitCheck() != B_OK) if (InitCheck() != B_OK)
return false; return false;
if(IsUp()) if (IsUp())
return true; return true;
fEthernetIfnet = FindPPPoEInterface(finterfaceName);
if (fEthernetIfnet == NULL) {
dprintf("%s::%s: fEthernetIfnet %s not found\n", __FILE__, __func__, finterfaceName);
return false;
}
memcpy(fEtherAddr, fEthernetIfnet->address.data, ETHER_ADDRESS_LENGTH);
dprintf("ppp's corresponding addr is %02x:%02x:%02x:%02x:%02x:%02x\n",
fEtherAddr[0], fEtherAddr[1], fEtherAddr[2], fEtherAddr[3],
fEtherAddr[4], fEtherAddr[5]);
if (fEthernetIfnet->module == NULL) {
dprintf("%s::%s: fEthernetIfnet->module not found\n", __FILE__,
__func__);
return false;
}
add_device(this); add_device(this);
fState = INITIAL; fState = INITIAL;
// reset state // reset state
if(fAttempts > PPPoE_MAX_ATTEMPTS) { if (fAttempts > PPPoE_MAX_ATTEMPTS) {
fAttempts = 0; fAttempts = 0;
return false; return false;
} }
++fAttempts; ++fAttempts;
// reset connection settings // reset connection settings
memset(fPeer, 0xFF, sizeof(fPeer)); memset(fPeer, 0xFF, sizeof(fPeer));
// create PADI // create PADI
DiscoveryPacket discovery(PADI); DiscoveryPacket discovery(PADI);
if(ServiceName()) if (ServiceName())
discovery.AddTag(SERVICE_NAME, ServiceName(), strlen(ServiceName())); discovery.AddTag(SERVICE_NAME, ServiceName(), strlen(ServiceName()));
else else
discovery.AddTag(SERVICE_NAME, NULL, 0); discovery.AddTag(SERVICE_NAME, NULL, 0);
discovery.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq)); discovery.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
discovery.AddTag(END_OF_LIST, NULL, 0); discovery.AddTag(END_OF_LIST, NULL, 0);
// set up PPP header // set up PPP header
struct mbuf *packet = discovery.ToMbuf(MTU()); net_buffer *packet = discovery.ToNetBuffer(MTU());
if(!packet) if (!packet)
return false; return false;
// create destination // create ether header
struct ether_header *ethernetHeader; NetBufferPrepend<ether_header> ethernetHeader(packet);
struct sockaddr destination; if (ethernetHeader.Status() != B_OK)
memset(&destination, 0, sizeof(destination)); return false;
destination.sa_family = AF_UNSPEC; ether_header &header = ethernetHeader.Data();
// raw packet with ethernet header
ethernetHeader = (struct ether_header*) destination.sa_data; memset(header.destination, 0xff, ETHER_ADDRESS_LENGTH);
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC; memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer)); header.type = htons(ETHER_TYPE_PPPOE_DISCOVERY);
ethernetHeader.Sync();
// raw packet with ethernet header
// check if we are allowed to go up now (user intervention might disallow that) // check if we are allowed to go up now (user intervention might disallow that)
if(fAttempts > 0 && !UpStarted()) { if (fAttempts > 0 && !UpStarted()) {
fAttempts = 0; fAttempts = 0;
remove_device(this); remove_device(this);
DownEvent(); DownEvent();
return true; return true;
// there was no error // there was no error
} }
fState = PADI_SENT; fState = PADI_SENT;
// needed before sending, otherwise we might not get all packets // needed before sending, otherwise we might not get all packets
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK) { status_t status = gStackModule->register_device_handler(fEthernetIfnet,
B_NET_FRAME_TYPE_PPPOE_DISCOVERY, &pppoe_input, NULL);
if (status != B_OK)
return false;
status = gStackModule->register_device_handler(fEthernetIfnet,
B_NET_FRAME_TYPE_PPPOE, &pppoe_input, NULL);
if (status != B_OK)
return false;
if (EthernetIfnet()->module->send_data(EthernetIfnet(), packet) != B_OK) {
fState = INITIAL; fState = INITIAL;
fAttempts = 0; fAttempts = 0;
ERROR("PPPoEDevice::Up(): EthernetIfnet()->output() failed!\n"); ERROR("PPPoEDevice::Up(): EthernetIfnet()->output() failed!\n");
return false; return false;
} }
dprintf("PPPoEDevice::Up(): EthernetIfnet()->output() success!\n");
fNextTimeout = system_time() + PPPoE_TIMEOUT; fNextTimeout = system_time() + PPPoE_TIMEOUT;
return true; return true;
} }
@@ -168,36 +226,41 @@ bool
PPPoEDevice::Down() PPPoEDevice::Down()
{ {
TRACE("PPPoEDevice: Down()\n"); TRACE("PPPoEDevice: Down()\n");
gStackModule->unregister_device_handler(fEthernetIfnet,
B_NET_FRAME_TYPE_PPPOE_DISCOVERY);
gStackModule->unregister_device_handler(fEthernetIfnet,
B_NET_FRAME_TYPE_PPPOE);
remove_device(this); remove_device(this);
if(InitCheck() != B_OK) if (InitCheck() != B_OK)
return false; return false;
fState = INITIAL; fState = INITIAL;
fAttempts = 0; fAttempts = 0;
fNextTimeout = 0; fNextTimeout = 0;
// disable timeouts // disable timeouts
if(!IsUp()) { if (!IsUp()) {
DownEvent(); DownEvent();
return true; return true;
} }
DownStarted(); DownStarted();
// this tells StateMachine that DownEvent() does not mean we lost connection // this tells StateMachine that DownEvent() does not mean we lost connection
// create PADT // create PADT
DiscoveryPacket discovery(PADT, SessionID()); DiscoveryPacket discovery(PADT, SessionID());
discovery.AddTag(END_OF_LIST, NULL, 0); discovery.AddTag(END_OF_LIST, NULL, 0);
struct mbuf *packet = discovery.ToMbuf(MTU()); net_buffer *packet = discovery.ToNetBuffer(MTU());
if(!packet) { if (!packet) {
ERROR("PPPoEDevice::Down(): ToMbuf() failed; MTU=%ld\n", MTU()); ERROR("PPPoEDevice::Down(): ToNetBuffer() failed; MTU=%ld\n", MTU());
DownEvent(); DownEvent();
return false; return false;
} }
// create destination // create destination
struct ether_header *ethernetHeader; struct ether_header *ethernetHeader;
struct sockaddr destination; struct sockaddr destination;
@@ -205,15 +268,15 @@ PPPoEDevice::Down()
destination.sa_family = AF_UNSPEC; destination.sa_family = AF_UNSPEC;
// raw packet with ethernet header // raw packet with ethernet header
ethernetHeader = (struct ether_header*) destination.sa_data; ethernetHeader = (struct ether_header*) destination.sa_data;
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC; ethernetHeader->type = ETHER_TYPE_PPPOE_DISCOVERY;
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer)); memcpy(ethernetHeader->destination, fPeer, sizeof(fPeer));
// reset connection settings // reset connection settings
memset(fPeer, 0xFF, sizeof(fPeer)); memset(fPeer, 0xFF, sizeof(fPeer));
EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL); EthernetIfnet()->module->send_data(EthernetIfnet(), packet);
DownEvent(); DownEvent();
return true; return true;
} }
@@ -242,220 +305,261 @@ PPPoEDevice::CountOutputBytes() const
status_t status_t
PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber) PPPoEDevice::Send(net_buffer *packet, uint16 protocolNumber)
{ {
// Send() is only for PPP packets. PPPoE packets are sent directly to ethernet. // Send() is only for PPP packets. PPPoE packets are sent directly to ethernet.
TRACE("PPPoEDevice: Send()\n"); TRACE("PPPoEDevice: Send()\n");
if(!packet) if (!packet)
return B_ERROR; return B_ERROR;
else if(InitCheck() != B_OK || protocolNumber != 0) { else if (InitCheck() != B_OK || protocolNumber != 0) {
ERROR("PPPoEDevice::Send(): InitCheck() != B_OK!\n"); ERROR("PPPoEDevice::Send(): InitCheck() != B_OK!\n");
m_freem(packet); gBufferModule->free(packet);
return B_ERROR; return B_ERROR;
} }
if(!IsUp()) { if (!IsUp()) {
ERROR("PPPoEDevice::Send(): no connection!\n"); ERROR("PPPoEDevice::Send(): no connection!\n");
m_freem(packet); gBufferModule->free(packet);
return PPP_NO_CONNECTION; return PPP_NO_CONNECTION;
} }
uint16 length = packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : packet->m_len; uint16 length = packet->size;
// encapsulate packet into pppoe header // encapsulate packet into pppoe header
M_PREPEND(packet, PPPoE_HEADER_SIZE); NetBufferPrepend<pppoe_header> bufferheader(packet);
pppoe_header *header = mtod(packet, pppoe_header*); if (bufferheader.Status() != B_OK)
header->version = PPPoE_VERSION; return B_ERROR;
header->type = PPPoE_TYPE; pppoe_header &header = bufferheader.Data();
header->code = 0x00; header.version = PPPoE_VERSION;
header->sessionID = SessionID(); header.type = PPPoE_TYPE;
header->length = htons(length); header.code = 0x00;
header.sessionID = SessionID();
// create destination header.length = htons(length);
struct ether_header *ethernetHeader; bufferheader.Sync();
struct sockaddr destination;
memset(&destination, 0, sizeof(destination)); // create ether header
destination.sa_family = AF_UNSPEC; NetBufferPrepend<ether_header> ethernetHeader(packet);
// raw packet with ethernet header if (ethernetHeader.Status() != B_OK)
ethernetHeader = (struct ether_header*) destination.sa_data; return false;
ethernetHeader->ether_type = ETHERTYPE_PPPOE; ether_header &ethheader = ethernetHeader.Data();
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
memcpy(ethheader.destination, fPeer, ETHER_ADDRESS_LENGTH);
if(!packet || !mtod(packet, pppoe_header*)) memcpy(ethheader.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
ethheader.type = htons(ETHER_TYPE_PPPOE);
ethernetHeader.Sync();
// raw packet with ethernet header
if (!packet)
ERROR("PPPoEDevice::Send(): packet is NULL!\n"); ERROR("PPPoEDevice::Send(): packet is NULL!\n");
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK) { if (EthernetIfnet()->module->send_data(EthernetIfnet(), packet) != B_OK) {
ERROR("PPPoEDevice::Send(): EthernetIfnet()->output() failed!\n"); ERROR("PPPoEDevice::Send(): EthernetIfnet()->output() failed!\n");
remove_device(this); remove_device(this);
DownEvent(); DownEvent();
// DownEvent() without DownStarted() indicates connection lost // DownEvent() without DownStarted() indicates connection lost
return PPP_NO_CONNECTION; return PPP_NO_CONNECTION;
} }
return B_OK; return B_OK;
} }
status_t status_t
PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber) PPPoEDevice::Receive(net_buffer *packet, uint16 protocolNumber)
{ {
if(!packet) TRACE("%s entering %s: protocolNumber:%x\n", __FILE__, __func__, protocolNumber);
if (!packet)
return B_ERROR; return B_ERROR;
else if(InitCheck() != B_OK || IsDown()) {
m_freem(packet); if (InitCheck() != B_OK || IsDown()) {
dprintf("PPPoED InitCheck fail or IsDown\n");
// gBufferModule->free(packet);
dprintf("PPPoEDevice::Receive fail\n");
return B_ERROR; return B_ERROR;
} }
complete_pppoe_header *completeHeader = mtod(packet, complete_pppoe_header*);
if(!completeHeader) {
m_freem(packet);
return B_ERROR;
}
uint8 ethernetSource[6]; uint8 ethernetSource[6];
memcpy(ethernetSource, completeHeader->ethernetHeader.ether_shost, sizeof(fPeer)); struct sockaddr_dl& source = *(struct sockaddr_dl*)packet->source;
status_t result = B_OK; memcpy(ethernetSource, source.sdl_data, sizeof(fPeer));
if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOE) { int32 PPP_Packet_Type = B_NET_FRAME_TYPE(source.sdl_type,
m_adj(packet, ETHER_HDR_LEN); ntohs(source.sdl_e_type));
pppoe_header *header = mtod(packet, pppoe_header*); // bufferheader.Remove();
// bufferheader.Sync();
if(!IsUp() || header->version != PPPoE_VERSION || header->type != PPPoE_TYPE
|| header->code != 0x0 || header->sessionID != SessionID()) { if (PPP_Packet_Type == B_NET_FRAME_TYPE_PPPOE) {
m_freem(packet); TRACE("ETHER_TYPE_PPPOE\n");
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
if (bufferheader.Status() != B_OK) {
TRACE("creat NetBufferHeaderReader fail\n");
return B_ERROR; return B_ERROR;
} }
pppoe_header &header = bufferheader.Data();
m_adj(packet, PPPoE_HEADER_SIZE); uint16 ppppoe_payload = ntohs(header.length);
if (!IsUp() || header.version != PPPoE_VERSION || header.type != PPPoE_TYPE
|| header.code != 0x0 || header.sessionID != SessionID()) {
// gBufferModule->free(packet);
TRACE("basic pppoe header check fail\n");
return B_ERROR;
}
bufferheader.Remove();
bufferheader.Sync();
// trim the packet according to actual pppoe_payload
gBufferModule->trim(packet, ppppoe_payload);
return Interface().ReceiveFromDevice(packet); return Interface().ReceiveFromDevice(packet);
} else if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC) { }
m_adj(packet, ETHER_HDR_LEN);
pppoe_header *header = mtod(packet, pppoe_header*); if (PPP_Packet_Type == B_NET_FRAME_TYPE_PPPOE_DISCOVERY) {
dprintf("ETHER_TYPE_PPPOE_DISCOVERY\n");
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
if (bufferheader.Status() != B_OK) {
dprintf("create NetBufferHeaderReader fail\n");
return B_ERROR;
}
pppoe_header &header = bufferheader.Data();
// we do not need to check HOST_UNIQ tag as this is done in pppoe.cpp // we do not need to check HOST_UNIQ tag as this is done in pppoe.cpp
if(header->version != PPPoE_VERSION || header->type != PPPoE_TYPE) { if (header.version != PPPoE_VERSION || header.type != PPPoE_TYPE) {
m_freem(packet); // gBufferModule->free(packet);
dprintf("PPPoEDevice::Receive fail version type wrong\n");
return B_ERROR; return B_ERROR;
} }
if(IsDown()) { if (IsDown()) {
m_freem(packet); // gBufferModule->free(packet);
dprintf("PPPoEDevice::Receive fail PPPoEDev IsDown\n");
return B_ERROR; return B_ERROR;
} }
DiscoveryPacket discovery(packet); DiscoveryPacket discovery(packet);
switch(discovery.Code()) { switch(discovery.Code()) {
case PADO: { case PADO: {
if(fState != PADI_SENT) { dprintf("processing PADO\n");
m_freem(packet); if (fState != PADI_SENT) {
// gBufferModule->free(packet);
dprintf("PPPoEDevice::Receive faile not PADI_Sent \n");
return B_OK; return B_OK;
} }
bool hasServiceName = false, hasACName = false; bool hasServiceName = false, hasACName = false;
pppoe_tag *tag; pppoe_tag *tag;
DiscoveryPacket reply(PADR); DiscoveryPacket reply(PADR);
for(int32 index = 0; index < discovery.CountTags(); index++) { for (int32 index = 0; index < discovery.CountTags(); index++) {
tag = discovery.TagAt(index); tag = discovery.TagAt(index);
if(!tag) if (!tag)
continue; continue;
switch(tag->type) { switch (tag->type) {
case SERVICE_NAME: case SERVICE_NAME:
if(!hasServiceName && (!ServiceName() if (!hasServiceName && (!ServiceName()
|| (strlen(ServiceName()) == tag->length) || ((strlen(ServiceName()) == tag->length)
&& !memcmp(tag->data, ServiceName(), && !memcmp(tag->data, ServiceName(),
tag->length))) { tag->length)))) {
hasServiceName = true; hasServiceName = true;
reply.AddTag(tag->type, tag->data, tag->length); reply.AddTag(tag->type, tag->data, tag->length);
} }
break; break;
case AC_NAME: case AC_NAME:
if(!hasACName && (!ACName() if (!hasACName && (!ACName()
|| (strlen(ACName()) == tag->length) || ((strlen(ACName()) == tag->length)
&& !memcmp(tag->data, ACName(), && !memcmp(tag->data, ACName(),
tag->length))) { tag->length)))) {
hasACName = true; hasACName = true;
reply.AddTag(tag->type, tag->data, tag->length); reply.AddTag(tag->type, tag->data, tag->length);
} }
break; break;
case AC_COOKIE: case AC_COOKIE:
case RELAY_SESSION_ID: case RELAY_SESSION_ID:
reply.AddTag(tag->type, tag->data, tag->length); reply.AddTag(tag->type, tag->data, tag->length);
break; break;
case SERVICE_NAME_ERROR: case SERVICE_NAME_ERROR:
case AC_SYSTEM_ERROR: case AC_SYSTEM_ERROR:
case GENERIC_ERROR: case GENERIC_ERROR:
m_freem(packet); // gBufferModule->free(packet);
dprintf("PPPoEDevice::generic error faile\n");
return B_ERROR; return B_ERROR;
break; break;
default: default:
; ;
} }
} }
if(!hasServiceName) { if (!hasServiceName) {
m_freem(packet); // gBufferModule->free(packet);
dprintf("PPPoEDevice::Receive faile no svc name\n");
return B_ERROR; return B_ERROR;
} }
dprintf("reply.AddTag\n");
reply.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq)); reply.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
reply.AddTag(END_OF_LIST, NULL, 0); reply.AddTag(END_OF_LIST, NULL, 0);
struct mbuf *replyPacket = reply.ToMbuf(MTU()); net_buffer *replyPacket = reply.ToNetBuffer(MTU());
if(!replyPacket) { if (!replyPacket) {
m_freem(packet); // gBufferModule->free(packet);
dprintf("PPPoEDevice::Receive fail no reply pack\n");
return B_ERROR; return B_ERROR;
} }
memcpy(fPeer, ethernetSource, sizeof(fPeer)); memcpy(fPeer, ethernetSource, ETHER_ADDRESS_LENGTH);
// create destination // create ether header
struct ether_header *ethernetHeader; NetBufferPrepend<ether_header> ethernetHeader(replyPacket);
struct sockaddr destination; if (ethernetHeader.Status() != B_OK)
memset(&destination, 0, sizeof(destination)); return false;
destination.sa_family = AF_UNSPEC; ether_header &header = ethernetHeader.Data();
// raw packet with ethernet header
ethernetHeader = (struct ether_header*) destination.sa_data; memcpy(header.destination, fPeer, ETHER_ADDRESS_LENGTH);
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC; memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer)); header.type=htons(ETHER_TYPE_PPPOE_DISCOVERY);
ethernetHeader.Sync();
// raw packet with ethernet header
fState = PADR_SENT; fState = PADR_SENT;
if(EthernetIfnet()->output(EthernetIfnet(), replyPacket, &destination, if (EthernetIfnet()->module->send_data(EthernetIfnet(), replyPacket) != B_OK) {
NULL) != B_OK) { gBufferModule->free(replyPacket);
m_freem(packet); dprintf("PPPoEDevice::Receive fail send PADR\n");
return B_ERROR; return B_ERROR;
} }
fNextTimeout = system_time() + PPPoE_TIMEOUT; fNextTimeout = system_time() + PPPoE_TIMEOUT;
} break; }
break;
case PADS: case PADS:
if(fState != PADR_SENT dprintf("procesing PADS\n");
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) { if (fState != PADR_SENT
m_freem(packet); || memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
// gBufferModule->free(packet);
dprintf("PPPoEDevice::Receive PADS but no PADR sent\n");
return B_ERROR; return B_ERROR;
} }
fSessionID = header->sessionID; fSessionID = header.sessionID;
fState = OPENED; fState = OPENED;
fNextTimeout = 0; fNextTimeout = 0;
UpEvent(); UpEvent();
break; break;
case PADT: case PADT:
if(!IsUp() dprintf("procesing PADT\n");
if (!IsUp()
|| memcmp(ethernetSource, fPeer, sizeof(fPeer)) || memcmp(ethernetSource, fPeer, sizeof(fPeer))
|| header->sessionID != SessionID()) { || header.sessionID != SessionID()) {
m_freem(packet); // gBufferModule->free(packet);
dprintf("PPPoEDevice::Receive fail not up yet\n");
return B_ERROR; return B_ERROR;
} }
fState = INITIAL; fState = INITIAL;
fAttempts = 0; fAttempts = 0;
fSessionID = 0; fSessionID = 0;
@@ -463,16 +567,17 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
remove_device(this); remove_device(this);
DownEvent(); DownEvent();
break; break;
default: default:
m_freem(packet); dprintf("PPPoEDevice::Receive fail unknown pppoed code\n");
// gBufferModule->free(packet);
return B_ERROR; return B_ERROR;
} }
} else }
result = B_ERROR;
dprintf("PPPoEDevice::Receive PADX fine!\n");
m_freem(packet); // gBufferModule->free(packet);
return result; return B_OK;
} }
@@ -480,13 +585,12 @@ void
PPPoEDevice::Pulse() PPPoEDevice::Pulse()
{ {
// We use Pulse() for timeout of connection establishment. // We use Pulse() for timeout of connection establishment.
if (fNextTimeout == 0 || IsUp() || IsDown())
if(fNextTimeout == 0 || IsUp() || IsDown())
return; return;
// check if timed out // check if timed out
if(system_time() >= fNextTimeout) { if (system_time() >= fNextTimeout) {
if(!Up()) if (!Up())
UpFailedEvent(); UpFailedEvent();
} }
} }
@@ -10,6 +10,9 @@
#include <KPPPDevice.h> #include <KPPPDevice.h>
#include <net/if_types.h>
#include <net_stack.h>
enum pppoe_state { enum pppoe_state {
INITIAL, INITIAL,
@@ -25,7 +28,7 @@ class PPPoEDevice : public KPPPDevice {
public: public:
PPPoEDevice(KPPPInterface& interface, driver_parameter *settings); PPPoEDevice(KPPPInterface& interface, driver_parameter *settings);
ifnet *EthernetIfnet() const net_device *EthernetIfnet() const
{ return fEthernetIfnet; } { return fEthernetIfnet; }
const uint8 *Peer() const const uint8 *Peer() const
@@ -50,17 +53,19 @@ class PPPoEDevice : public KPPPDevice {
virtual uint32 CountOutputBytes() const; virtual uint32 CountOutputBytes() const;
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber = 0); virtual status_t Send(net_buffer *packet, uint16 protocolNumber = 0);
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber = 0); virtual status_t Receive(net_buffer *packet, uint16 protocolNumber = 0);
virtual void Pulse(); virtual void Pulse();
private: private:
ifnet *fEthernetIfnet; net_device *fEthernetIfnet;
uint8 fPeer[6]; uint8 fPeer[6];
uint8 fEtherAddr[6];
uint16 fSessionID; uint16 fSessionID;
uint32 fHostUniq; uint32 fHostUniq;
const char *fACName, *fServiceName; const char *fACName, *fServiceName;
const char *finterfaceName;
uint32 fAttempts; uint32 fAttempts;
bigtime_t fNextTimeout; bigtime_t fNextTimeout;
+217 -130
View File
@@ -5,34 +5,46 @@
#include <KernelExport.h> #include <KernelExport.h>
#include <driver_settings.h> #include <driver_settings.h>
#include <core_funcs.h>
#include <net_module.h>
#include <ethernet_module.h> #include <lock.h>
#include <util/AutoLock.h>
#include <ByteOrder.h>
#include <net/if_types.h>
#include <net/if_dl.h>
#include <net/if.h>
#include <sys/sockio.h>
#include <net_buffer.h>
#include <net_datalink.h> // for get_interface and control
#include <net_stack.h>
#include <NetBufferUtilities.h>
#include <KPPPInterface.h> #include <KPPPInterface.h>
#include <KPPPModule.h> #include <KPPPModule.h>
#include <KPPPUtils.h> #include <KPPPUtils.h>
#include <LockerHelper.h>
#include "PPPoEDevice.h" #include "PPPoEDevice.h"
#include "DiscoveryPacket.h" #include "DiscoveryPacket.h"
typedef struct pppoe_query { typedef struct pppoe_query {
ifnet *ethernetIfnet; net_device *ethernetIfnet;
uint32 hostUniq; uint32 hostUniq;
thread_id receiver; thread_id receiver;
} pppoe_query; } pppoe_query;
#define PPPoE_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pppoe" #define PPPoE_MODULE_NAME "network/ppp/pppoe"
net_stack_module_info *gStackModule = NULL;
net_buffer_module_info *gBufferModule = NULL;
net_datalink_module_info *sDatalinkModule = NULL;
struct core_module_info *core = NULL;
static struct ethernet_module_info *sEthernet;
static int32 sHostUniq = 0; static int32 sHostUniq = 0;
status_t std_ops(int32 op, ...); status_t std_ops(int32 op, ...);
static BLocker sLock("PPPoEList"); // static mutex sLock("PPPoEList");
static TemplateList<PPPoEDevice*> *sDevices; static TemplateList<PPPoEDevice*> *sDevices;
static TemplateList<pppoe_query*> *sQueries; static TemplateList<pppoe_query*> *sQueries;
@@ -44,51 +56,75 @@ SendQueryPacket(pppoe_query *query, DiscoveryPacket& discovery)
char data[PPPoE_QUERY_REPORT_SIZE]; char data[PPPoE_QUERY_REPORT_SIZE];
uint32 position = sizeof(uint32); uint32 position = sizeof(uint32);
pppoe_tag *acName = discovery.TagWithType(AC_NAME); pppoe_tag *acName = discovery.TagWithType(AC_NAME);
if(acName) { if (acName) {
if(acName->length >= PPPoE_QUERY_REPORT_SIZE) if (acName->length >= PPPoE_QUERY_REPORT_SIZE)
return; return;
memcpy(data + position, acName->data, acName->length); memcpy(data + position, acName->data, acName->length);
position += acName->length; position += acName->length;
} }
data[position++] = 0; data[position++] = 0;
pppoe_tag *tag; pppoe_tag *tag;
for(int32 index = 0; index < discovery.CountTags(); index++) { for (int32 index = 0; index < discovery.CountTags(); index++) {
tag = discovery.TagAt(index); tag = discovery.TagAt(index);
if(tag && tag->type == SERVICE_NAME) { if (tag && tag->type == SERVICE_NAME) {
if(position + tag->length >= PPPoE_QUERY_REPORT_SIZE) if (position + tag->length >= PPPoE_QUERY_REPORT_SIZE)
return; return;
memcpy(data + position, tag->data, tag->length); memcpy(data + position, tag->data, tag->length);
position += tag->length; position += tag->length;
data[position++] = 0; data[position++] = 0;
} }
} }
memcpy(data, &position, sizeof(uint32)); memcpy(data, &position, sizeof(uint32));
// add the total length // add the total length
send_data_with_timeout(query->receiver, PPPoE_QUERY_REPORT, data, send_data_with_timeout(query->receiver, PPPoE_QUERY_REPORT, data,
PPPoE_QUERY_REPORT_SIZE, 700000); PPPoE_QUERY_REPORT_SIZE, 700000);
} }
ifnet* net_interface *
get_interface_by_name(net_domain *domain, const char *name)
{
ifreq request;
memset(&request, 0, sizeof(request));
size_t size = sizeof(request);
strlcpy(request.ifr_name, name, IF_NAMESIZE);
if (sDatalinkModule->control(domain, SIOCGIFINDEX, &request, &size) != B_OK) {
TRACE("sDatalinkModule->control failure\n");
return NULL;
}
return sDatalinkModule->get_interface(domain, request.ifr_index);
}
net_device*
FindPPPoEInterface(const char *name) FindPPPoEInterface(const char *name)
{ {
if(!name) if (!name)
return NULL;
net_interface* ethernetInterfaceOfPPPOE = NULL;
net_domain* domain = NULL;
domain = gStackModule->get_domain(AF_INET);
ethernetInterfaceOfPPPOE = get_interface_by_name(domain, name);
if (ethernetInterfaceOfPPPOE == NULL) {
TRACE("get_interface_by_name can not find eth\n");
return NULL; return NULL;
ifnet *current = get_interfaces();
for(; current; current = current->if_next) {
if(current->if_type == IFT_ETHER && current->if_name
&& !strcmp(current->if_name, name))
return current;
} }
if (ethernetInterfaceOfPPPOE->device)
return ethernetInterfaceOfPPPOE->device;
return NULL; return NULL;
} }
@@ -104,9 +140,9 @@ void
add_device(PPPoEDevice *device) add_device(PPPoEDevice *device)
{ {
TRACE("PPPoE: add_device()\n"); TRACE("PPPoE: add_device()\n");
LockerHelper locker(sLock); // MutexLocker locker(sLock);
if(!sDevices->HasItem(device)) if (!sDevices->HasItem(device))
sDevices->AddItem(device); sDevices->AddItem(device);
} }
@@ -115,85 +151,125 @@ void
remove_device(PPPoEDevice *device) remove_device(PPPoEDevice *device)
{ {
TRACE("PPPoE: remove_device()\n"); TRACE("PPPoE: remove_device()\n");
LockerHelper locker(sLock); // MutexLocker locker(sLock);
sDevices->RemoveItem(device); sDevices->RemoveItem(device);
} }
static status_t
void pppoe_input(void *cookie, net_device *_device, net_buffer *packet)
pppoe_input(struct mbuf *packet)
{ {
if(!packet) if (!packet)
return; return B_ERROR;
ifnet *sourceIfnet = packet->m_pkthdr.rcvif; NetBufferHeaderReader<pppoe_header> bufferheader(packet);
complete_pppoe_header *header = mtod(packet, complete_pppoe_header*); if (bufferheader.Status() != B_OK)
return B_ERROR;
pppoe_header &header = bufferheader.Data();
// remove the following lines when pppoe server is enabled
if (header.code == PADI) {
TRACE("PADI packet received, ignoreing!\n");
gBufferModule->free(packet);
return B_OK;
}
if (header.code == PADO || header.code == PADR || header.code == PADS || header.code == PADT)
{
uint8 peerEtherAddr[ETHER_ADDRESS_LENGTH];
struct sockaddr_dl& source = *(struct sockaddr_dl*)packet->source;
memcpy(peerEtherAddr, source.sdl_data, ETHER_ADDRESS_LENGTH);
const char *str = header.code == PADI ? "PADI" :
header.code == PADO ? "PADO" :
header.code == PADR ? "PADR" :
header.code == PADS ? "PADS" :
"PADT" ;
dprintf("%s from:%02x:%02x:%02x:%02x:%02x:%02x code:%02x\n", str,
peerEtherAddr[0], peerEtherAddr[1], peerEtherAddr[2],
peerEtherAddr[3], peerEtherAddr[4], peerEtherAddr[5],
header.code);
}
PPPoEDevice *device; PPPoEDevice *device;
pppoe_query *query; pppoe_query *query;
LockerHelper locker(sLock); sockaddr_dl& linkAddress = *(sockaddr_dl*)packet->source;
int32 specificType = B_NET_FRAME_TYPE(linkAddress.sdl_type,
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC ntohs(linkAddress.sdl_e_type));
&& header->pppoeHeader.length <= PPPoE_QUERY_REPORT_SIZE) {
for(int32 index = 0; index < sDevices->CountItems(); index++) { // MutexLocker locker(sLock);
if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
&& ntohs(header.length) <= PPPoE_QUERY_REPORT_SIZE) {
for (int32 index = 0; index < sDevices->CountItems(); index++) {
query = sQueries->ItemAt(index); query = sQueries->ItemAt(index);
if(query && query->ethernetIfnet == sourceIfnet) { if (query) {// && query->ethernetIfnet == sourceIfnet) {
if(header->pppoeHeader.code == PADO) { if (header.code == PADO) {
DiscoveryPacket discovery(packet, ETHER_HDR_LEN); DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
if(discovery.InitCheck() != B_OK) { if (discovery.InitCheck() != B_OK) {
ERROR("PPPoE: received corrupted discovery packet!\n"); ERROR("PPPoE: received corrupted discovery packet!\n");
m_freem(packet); // gBufferModule->free(packet);
return; return B_ERROR;
} }
pppoe_tag *hostTag = discovery.TagWithType(HOST_UNIQ); pppoe_tag *hostTag = discovery.TagWithType(HOST_UNIQ);
if(hostTag && hostTag->length == 4 if (hostTag && hostTag->length == 4
&& *((uint32*)hostTag->data) == query->hostUniq) { && *((uint32*)hostTag->data) == query->hostUniq) {
SendQueryPacket(query, discovery); SendQueryPacket(query, discovery);
m_freem(packet); // gBufferModule->free(packet);
return; return B_ERROR;
} }
} }
} }
} }
} }
for(int32 index = 0; index < sDevices->CountItems(); index++) { TRACE("in pppoed processing sDevices->CountItems(): %ld\n", sDevices->CountItems());
for (int32 index = 0; index < sDevices->CountItems(); index++) {
device = sDevices->ItemAt(index); device = sDevices->ItemAt(index);
if(device && device->EthernetIfnet() == sourceIfnet) { TRACE("device->SessionID() %d, header.sessionID: %d\n", device->SessionID(),
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE header.sessionID);
&& header->pppoeHeader.sessionID == device->SessionID()) {
if (device) { // && device->EthernetIfnet() == sourceIfnet) {
if (specificType == B_NET_FRAME_TYPE_PPPOE
&& header.sessionID == device->SessionID()) {
TRACE("PPPoE: session packet\n"); TRACE("PPPoE: session packet\n");
device->Receive(packet); device->Receive(packet);
return; return B_OK;
} else if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC }
&& header->pppoeHeader.code != PADI
&& header->pppoeHeader.code != PADR if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
&& header.code != PADI
&& header.code != PADR
&& !device->IsDown()) { && !device->IsDown()) {
TRACE("PPPoE: discovery packet\n"); TRACE("PPPoE: discovery packet\n");
DiscoveryPacket discovery(packet, ETHER_HDR_LEN); DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
if(discovery.InitCheck() != B_OK) { if (discovery.InitCheck() != B_OK) {
ERROR("PPPoE: received corrupted discovery packet!\n"); ERROR("PPPoE: received corrupted discovery packet!\n");
m_freem(packet); gBufferModule->free(packet);
return; return B_OK;
} }
pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ); pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ);
if(header->pppoeHeader.code == PADT || (tag && tag->length == 4 if (header.code == PADT || (tag && tag->length == 4
&& *((uint32*)tag->data) == device->HostUniq())) { && *((uint32*)tag->data) == device->HostUniq())) {
device->Receive(packet); device->Receive(packet);
return; return B_OK;
} }
} }
} }
} }
ERROR("PPPoE: No device found for packet from: %s\n", sourceIfnet->if_name); ERROR("PPPoE: No device found for packet from: %s\n", "ethernet");
m_freem(packet); // gBufferModule->free(packet);
return B_ERROR;
} }
@@ -202,22 +278,22 @@ bool
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface, add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
driver_parameter *settings, ppp_module_key_type type) driver_parameter *settings, ppp_module_key_type type)
{ {
if(mainInterface.Mode() != PPP_CLIENT_MODE || type != PPP_DEVICE_KEY_TYPE) if (mainInterface.Mode() != PPP_CLIENT_MODE || type != PPP_DEVICE_KEY_TYPE)
return B_ERROR; return B_ERROR;
PPPoEDevice *device; PPPoEDevice *device;
bool success; bool success;
if(subInterface) { if (subInterface) {
device = new PPPoEDevice(*subInterface, settings); device = new PPPoEDevice(*subInterface, settings);
success = subInterface->SetDevice(device); success = subInterface->SetDevice(device);
} else { } else {
device = new PPPoEDevice(mainInterface, settings); device = new PPPoEDevice(mainInterface, settings);
success = mainInterface.SetDevice(device); success = mainInterface.SetDevice(device);
} }
TRACE("PPPoE: add_to(): %s\n", TRACE("PPPoE: add_to(): %s\n",
success && device && device->InitCheck() == B_OK ? "OK" : "ERROR"); success && device && device->InitCheck() == B_OK ? "OK" : "ERROR");
return success && device && device->InitCheck() == B_OK; return success && device && device->InitCheck() == B_OK;
} }
@@ -226,59 +302,62 @@ static
status_t status_t
control(uint32 op, void *data, size_t length) control(uint32 op, void *data, size_t length)
{ {
switch(op) { switch (op) {
case PPPoE_GET_INTERFACES: { case PPPoE_GET_INTERFACES: {
int32 position = 0, count = 0; int32 position = 0, count = 0;
char *names = (char*) data; char *names = (char*) data;
ifnet *current = get_interfaces(); net_device *current = NULL; // get_interfaces();
for(; current; current = current->if_next) { for (; current; current = NULL) {
if(current->if_type == IFT_ETHER && current->if_name) { if (current->type == IFT_ETHER && current->name) {
if(position + strlen(current->if_name) + 1 > length) if (position + strlen(current->name) + 1 > length)
return B_NO_MEMORY; return B_NO_MEMORY;
strcpy(names + position, current->if_name); strcpy(names + position, current->name);
position += strlen(current->if_name); position += strlen(current->name);
names[position++] = 0; names[position++] = 0;
++count; ++count;
} }
} }
return count; return count;
} }
case PPPoE_QUERY_SERVICES: { case PPPoE_QUERY_SERVICES: {
// XXX: as all modules are loaded on-demand we must wait for the results // XXX: as all modules are loaded on-demand we must wait for the results
if(!data || length != sizeof(pppoe_query_request)) if (!data || length != sizeof(pppoe_query_request))
return B_ERROR; return B_ERROR;
pppoe_query_request *request = (pppoe_query_request*) data; pppoe_query_request *request = (pppoe_query_request*) data;
pppoe_query query; pppoe_query query;
query.ethernetIfnet = FindPPPoEInterface(request->interfaceName); query.ethernetIfnet = FindPPPoEInterface(request->interfaceName);
if(!query.ethernetIfnet) if (!query.ethernetIfnet)
return B_BAD_VALUE; return B_BAD_VALUE;
query.hostUniq = NewHostUniq(); query.hostUniq = NewHostUniq();
query.receiver = request->receiver; query.receiver = request->receiver;
sLock.Lock(); {
sQueries->AddItem(&query); // MutexLocker tlocker(sLock);
sLock.Unlock(); TRACE("add query\n");
sQueries->AddItem(&query);
}
snooze(2000000); snooze(2000000);
// wait two seconds for results // wait two seconds for results
{
sLock.Lock(); // MutexLocker tlocker(sLock);
sQueries->RemoveItem(&query); TRACE("remove query\n");
sLock.Unlock(); sQueries->RemoveItem(&query);
}
} break; } break;
default: default:
return B_ERROR; return B_ERROR;
} }
return B_OK; return B_OK;
} }
@@ -296,40 +375,48 @@ static ppp_module_info pppoe_module = {
_EXPORT _EXPORT
status_t status_t
std_ops(int32 op, ...) std_ops(int32 op, ...)
{ {
switch(op) { switch(op) {
case B_MODULE_INIT: case B_MODULE_INIT:
if(get_module(NET_CORE_MODULE_NAME, (module_info**)&core) != B_OK) if (get_module(NET_STACK_MODULE_NAME,
(module_info**)&gStackModule) != B_OK)
return B_ERROR; return B_ERROR;
if(get_module(NET_ETHERNET_MODULE_NAME, if (get_module(NET_DATALINK_MODULE_NAME,
(module_info**) &sEthernet) != B_OK) { (module_info **)&sDatalinkModule) != B_OK) {
put_module(NET_CORE_MODULE_NAME); put_module(NET_STACK_MODULE_NAME);
return B_ERROR; return B_ERROR;
} }
set_max_linkhdr(2 + PPPoE_HEADER_SIZE + ETHER_HDR_LEN); if (get_module(NET_BUFFER_MODULE_NAME,
(module_info **)&gBufferModule) != B_OK) {
put_module(NET_DATALINK_MODULE_NAME);
put_module(NET_STACK_MODULE_NAME);
return B_ERROR;
}
// set_max_linkhdr(2 + PPPoE_HEADER_SIZE + ETHER_HDR_LEN);
// 2 bytes for PPP header // 2 bytes for PPP header
sDevices = new TemplateList<PPPoEDevice*>; sDevices = new TemplateList<PPPoEDevice*>;
sQueries = new TemplateList<pppoe_query*>; sQueries = new TemplateList<pppoe_query*>;
sEthernet->set_pppoe_receiver(pppoe_input);
TRACE("PPPoE: Registered PPPoE receiver.\n"); TRACE("PPPoE: Registered PPPoE receiver.\n");
return B_OK; return B_OK;
case B_MODULE_UNINIT: case B_MODULE_UNINIT:
delete sQueries;
delete sDevices; delete sDevices;
sEthernet->unset_pppoe_receiver();
TRACE("PPPoE: Unregistered PPPoE receiver.\n"); TRACE("PPPoE: Unregistered PPPoE receiver.\n");
put_module(NET_CORE_MODULE_NAME); put_module(NET_BUFFER_MODULE_NAME);
put_module(NET_ETHERNET_MODULE_NAME); put_module(NET_DATALINK_MODULE_NAME);
break; put_module(NET_STACK_MODULE_NAME);
break;
default: default:
return B_ERROR; return B_ERROR;
} }
return B_OK; return B_OK;
} }
@@ -10,6 +10,9 @@ if $(TARGET_PLATFORM) != haiku {
# Unfortunately we get more than we want, namely all POSIX headers. # Unfortunately we get more than we want, namely all POSIX headers.
} }
UsePrivateKernelHeaders ;
UsePrivateHeaders net ;
UsePrivateHeaders libroot net ; UsePrivateHeaders libroot net ;
UsePrivateHeaders [ FDirName kernel ] ; UsePrivateHeaders [ FDirName kernel ] ;
UsePrivateHeaders [ FDirName kernel util ] ; UsePrivateHeaders [ FDirName kernel util ] ;
@@ -37,7 +40,6 @@ KernelStaticLibrary libkernelppp.a :
KPPPReportManager.cpp KPPPReportManager.cpp
KPPPStateMachine.cpp KPPPStateMachine.cpp
KPPPUtils.cpp KPPPUtils.cpp
Locker.cpp
settings_tools.cpp settings_tools.cpp
# integrated modules # integrated modules
@@ -49,7 +51,5 @@ KernelStaticLibrary libkernelppp.a :
SEARCH on [ FGristFiles kernel_cpp.cpp ] SEARCH on [ FGristFiles kernel_cpp.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel util ] ; = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
SEARCH on [ FGristFiles Locker.cpp ]
= [ FDirName $(HAIKU_TOP) src system kernel disk_device_manager ] ;
SEARCH on [ FGristFiles atomic.S ] SEARCH on [ FGristFiles atomic.S ]
= [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ; = [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
@@ -5,18 +5,20 @@
/*! \class KPPPConfigurePacket /*! \class KPPPConfigurePacket
\brief Helper class for LCP configure packets. \brief Helper class for LCP configure packets.
This class allows iterating over configure items and adding/removing items. This class allows iterating over configure items and adding/removing items.
*/ */
#include <ByteOrder.h>
#include <net_buffer.h>
#include <net_stack.h>
#include <KPPPConfigurePacket.h> #include <KPPPConfigurePacket.h>
#include <KPPPInterface.h> #include <KPPPInterface.h>
#include <core_funcs.h>
/*! \brief Constructor. /*! \brief Constructor.
\param code The code value (e.g.: PPP_CONFIGURE_REQUEST) of this packet. \param code The code value (e.g.: PPP_CONFIGURE_REQUEST) of this packet.
*/ */
KPPPConfigurePacket::KPPPConfigurePacket(uint8 code) KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
@@ -27,30 +29,33 @@ KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
//! Decodes a packet and adds its items to this object. //! Decodes a packet and adds its items to this object.
KPPPConfigurePacket::KPPPConfigurePacket(struct mbuf *packet) KPPPConfigurePacket::KPPPConfigurePacket(net_buffer *packet)
{ {
// decode packet // decode packet
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*); NetBufferHeaderReader<ppp_lcp_packet> bufferhead(packet);
if (bufferhead.Status() != B_OK)
SetID(header->id);
if (!SetCode(header->code))
return; return;
ppp_lcp_packet &header = bufferhead.Data();
uint16 length = ntohs(header->length);
SetID(header.id);
if (length < 6 || length > packet->m_len) if (!SetCode(header.code))
return;
uint16 length = ntohs(header.length);
if (length < 6 || length > packet->size)
return; return;
// there are no items (or one corrupted item) // there are no items (or one corrupted item)
int32 position = 0; int32 position = 0;
ppp_configure_item *item; ppp_configure_item *item;
while (position < length - 4) { while (position < length - 4) {
item = (ppp_configure_item*) (header->data + position); item = (ppp_configure_item*) (header.data + position);
if (item->length < 2) if (item->length < 2)
return; return;
// found a corrupted item // found a corrupted item
position += item->length; position += item->length;
AddItem(item); AddItem(item);
} }
@@ -72,23 +77,23 @@ KPPPConfigurePacket::SetCode(uint8 code)
// only configure codes are allowed! // only configure codes are allowed!
if (code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT) if (code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT)
return false; return false;
fCode = code; fCode = code;
return true; return true;
} }
/*! \brief Adds a new configure item to this packet. /*! \brief Adds a new configure item to this packet.
Make sure all values are correct because the item will be copied. If the item's Make sure all values are correct because the item will be copied. If the item's
length field is incorrect you will get bad results. length field is incorrect you will get bad results.
\param item The item. \param item The item.
\param index Item's index. Adds after the last item if not specified or negative. \param index Item's index. Adds after the last item if not specified or negative.
\return \c true if successful, \c false otherwise. \return \c true if successful, \c false otherwise.
\sa ppp_configure_item \sa ppp_configure_item
*/ */
bool bool
@@ -96,10 +101,10 @@ KPPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index)
{ {
if (!item || item->length < 2) if (!item || item->length < 2)
return false; return false;
ppp_configure_item *add = (ppp_configure_item*) malloc(item->length); ppp_configure_item *add = (ppp_configure_item*) malloc(item->length);
memcpy(add, item, item->length); memcpy(add, item, item->length);
bool status; bool status;
if (index < 0) if (index < 0)
status = fItems.AddItem(add); status = fItems.AddItem(add);
@@ -109,7 +114,7 @@ KPPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index)
free(add); free(add);
return false; return false;
} }
return true; return true;
} }
@@ -120,10 +125,10 @@ KPPPConfigurePacket::RemoveItem(ppp_configure_item *item)
{ {
if (!fItems.HasItem(item)) if (!fItems.HasItem(item))
return false; return false;
fItems.RemoveItem(item); fItems.RemoveItem(item);
free(item); free(item);
return true; return true;
} }
@@ -133,10 +138,10 @@ ppp_configure_item*
KPPPConfigurePacket::ItemAt(int32 index) const KPPPConfigurePacket::ItemAt(int32 index) const
{ {
ppp_configure_item *item = fItems.ItemAt(index); ppp_configure_item *item = fItems.ItemAt(index);
if (item == fItems.GetDefaultItem()) if (item == fItems.GetDefaultItem())
return NULL; return NULL;
return item; return item;
} }
@@ -146,56 +151,71 @@ ppp_configure_item*
KPPPConfigurePacket::ItemWithType(uint8 type) const KPPPConfigurePacket::ItemWithType(uint8 type) const
{ {
ppp_configure_item *item; ppp_configure_item *item;
for (int32 index = 0; index < CountItems(); index++) { for (int32 index = 0; index < CountItems(); index++) {
item = ItemAt(index); item = ItemAt(index);
if (item && item->type == type) if (item && item->type == type)
return item; return item;
} }
return NULL; return NULL;
} }
/*! \brief Converts this packet into an mbuf structure. /*! \brief Converts this packet into an net_buffer structure.
ATTENTION: You are responsible for freeing this packet by calling \c m_freem()! ATTENTION: You are responsible for freeing this packet by calling \c m_freem()!
\param MRU The interface's maximum receive unit (MRU). \param MRU The interface's maximum receive unit (MRU).
\param reserve Number of bytes to reserve at the beginning of the packet. \param reserve Number of bytes to reserve at the beginning of the packet.
\return The mbuf structure or \c NULL on error (e.g.: too big for given MRU). \return The net_buffer structure or \c NULL on error (e.g.: too big for given MRU).
*/ */
struct mbuf* net_buffer*
KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve) KPPPConfigurePacket::ToNetBuffer(uint32 MRU)
{ {
struct mbuf *packet = m_gethdr(MT_DATA); net_buffer *buffer = gBufferModule->create(256);
packet->m_data += reserve; if (buffer == NULL) {
TRACE("%s::%s: gBufferModule->create fail\n", __FILE__, __func__);
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*); return(NULL);
}
ppp_lcp_packet *header;
status_t status = gBufferModule->append_size(buffer, 1492, (void **)&header);
if (status != B_OK) {
TRACE("%s::%s: gBufferModule->append_size\n", __FILE__, __func__);
gBufferModule->free(buffer);
return(NULL);
}
header->code = Code(); header->code = Code();
header->id = ID(); header->id = ID();
uint16 length = 0; uint16 length = 0;
ppp_configure_item *item; ppp_configure_item *item;
for (int32 index = 0; index < CountItems(); index++) { for (int32 index = 0; index < CountItems(); index++) {
item = ItemAt(index); item = ItemAt(index);
// make sure we have enough space left // make sure we have enough space left
if (MRU - length < item->length) { if (MRU - length < item->length) {
m_freem(packet); gBufferModule->free(buffer);
return NULL; return NULL;
} }
memcpy(header->data + length, item, item->length); memcpy(header->data + length, item, item->length);
length += item->length; length += item->length;
} }
length += 4; length += 4;
header->length = htons(length); header->length = htons(length);
packet->m_pkthdr.len = packet->m_len = length;
status = gBufferModule->trim(buffer, length);
return packet; if (status < B_OK) {
dprintf("%s::%s: gBufferModule->trim\n", __FILE__, __func__);
gBufferModule->free(buffer);
return(NULL);
}
return buffer;
} }
@@ -5,7 +5,7 @@
/*! \class KPPPDevice /*! \class KPPPDevice
\brief Represents a device at the lowest level of the communcation stack. \brief Represents a device at the lowest level of the communcation stack.
A device may be, for example: Modem, PPPoE, PPTP. \n A device may be, for example: Modem, PPPoE, PPTP. \n
It encapsulates the packet and sends it over a line to the other end. It encapsulates the packet and sends it over a line to the other end.
The device is the first layer that receives a packet. The device is the first layer that receives a packet.
@@ -14,13 +14,12 @@
#include <KPPPDevice.h> #include <KPPPDevice.h>
#include <net/if.h> #include <net/if.h>
#include <core_funcs.h>
#include <PPPControl.h> #include <PPPControl.h>
/*! \brief Initializes the device. /*! \brief Initializes the device.
\param name The device's type name (e.g.: PPPoE). \param name The device's type name (e.g.: PPPoE).
\param overhead Length of the header that is prepended to each packet. \param overhead Length of the header that is prepended to each packet.
\param interface Owning interface. \param interface Owning interface.
@@ -46,12 +45,13 @@ KPPPDevice::~KPPPDevice()
/*! \brief Allows private extensions. /*! \brief Allows private extensions.
If you override this method you must call the parent's method for unknown ops. If you override this method you must call the parent's method for unknown ops.
*/ */
status_t status_t
KPPPDevice::Control(uint32 op, void *data, size_t length) KPPPDevice::Control(uint32 op, void *data, size_t length)
{ {
dprintf("KPPPDevice::Control\n");
switch (op) { switch (op) {
case PPPC_GET_DEVICE_INFO: case PPPC_GET_DEVICE_INFO:
{ {
@@ -89,7 +89,7 @@ KPPPDevice::IsAllowedToSend() const
//! This method is never used. //! This method is never used.
status_t status_t
KPPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber) KPPPDevice::Receive(net_buffer *packet, uint16 protocolNumber)
{ {
// let the interface handle the packet // let the interface handle the packet
if (protocolNumber == 0) if (protocolNumber == 0)
@@ -100,10 +100,10 @@ KPPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
/*! \brief Report that device is going up. /*! \brief Report that device is going up.
Called by Up(). \n Called by Up(). \n
From now on, the connection attempt can may be aborted by calling Down(). From now on, the connection attempt can may be aborted by calling Down().
\return \return
- \c true: You are allowed to connect. - \c true: You are allowed to connect.
- \c false: You should abort immediately. Down() will \e not be called! - \c false: You should abort immediately. Down() will \e not be called!
@@ -112,15 +112,15 @@ bool
KPPPDevice::UpStarted() KPPPDevice::UpStarted()
{ {
fConnectionPhase = PPP_ESTABLISHMENT_PHASE; fConnectionPhase = PPP_ESTABLISHMENT_PHASE;
return Interface().StateMachine().TLSNotify(); return Interface().StateMachine().TLSNotify();
} }
/*! \brief Report that device is going down. /*! \brief Report that device is going down.
Called by Down(). Called by Down().
\return \return
- \c true: You are allowed to disconnect. - \c true: You are allowed to disconnect.
- \c false: You must not disconnect! - \c false: You must not disconnect!
@@ -129,7 +129,7 @@ bool
KPPPDevice::DownStarted() KPPPDevice::DownStarted()
{ {
fConnectionPhase = PPP_TERMINATION_PHASE; fConnectionPhase = PPP_TERMINATION_PHASE;
return Interface().StateMachine().TLFNotify(); return Interface().StateMachine().TLFNotify();
} }
@@ -139,7 +139,7 @@ void
KPPPDevice::UpFailedEvent() KPPPDevice::UpFailedEvent()
{ {
fConnectionPhase = PPP_DOWN_PHASE; fConnectionPhase = PPP_DOWN_PHASE;
Interface().StateMachine().UpFailedEvent(); Interface().StateMachine().UpFailedEvent();
} }
@@ -149,7 +149,7 @@ void
KPPPDevice::UpEvent() KPPPDevice::UpEvent()
{ {
fConnectionPhase = PPP_ESTABLISHED_PHASE; fConnectionPhase = PPP_ESTABLISHED_PHASE;
Interface().StateMachine().UpEvent(); Interface().StateMachine().UpEvent();
} }
@@ -159,6 +159,6 @@ void
KPPPDevice::DownEvent() KPPPDevice::DownEvent()
{ {
fConnectionPhase = PPP_DOWN_PHASE; fConnectionPhase = PPP_DOWN_PHASE;
Interface().StateMachine().DownEvent(); Interface().StateMachine().DownEvent();
} }
File diff suppressed because it is too large Load Diff
@@ -5,7 +5,7 @@
/*! \class KPPPLCP /*! \class KPPPLCP
\brief The LCP protocol. \brief The LCP protocol.
Every PPP interface \e must have an LCP protocol. It is used for establishing Every PPP interface \e must have an LCP protocol. It is used for establishing
and terminating connections. \n and terminating connections. \n
When establishing a connecition the LCP protocol determines connection-specific When establishing a connecition the LCP protocol determines connection-specific
@@ -20,9 +20,12 @@
#include <KPPPOptionHandler.h> #include <KPPPOptionHandler.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <core_funcs.h>
#include <net_buffer.h>
#include <sys/socket.h> #include <sys/socket.h>
extern net_buffer_module_info *gBufferModule;
//! Creates a new LCP protocol for the given interface. //! Creates a new LCP protocol for the given interface.
KPPPLCP::KPPPLCP(KPPPInterface& interface) KPPPLCP::KPPPLCP(KPPPInterface& interface)
@@ -48,7 +51,7 @@ KPPPLCP::~KPPPLCP()
/*! \brief Adds a new option handler. /*! \brief Adds a new option handler.
NOTE: You can only add option handlers in \c PPP_DOWN_PHASE. \n NOTE: You can only add option handlers in \c PPP_DOWN_PHASE. \n
There may only be one handler per option type! There may only be one handler per option type!
*/ */
@@ -57,19 +60,19 @@ KPPPLCP::AddOptionHandler(KPPPOptionHandler *optionHandler)
{ {
if (!optionHandler || &optionHandler->Interface() != &Interface()) if (!optionHandler || &optionHandler->Interface() != &Interface())
return false; return false;
if (Interface().Phase() != PPP_DOWN_PHASE if (Interface().Phase() != PPP_DOWN_PHASE
|| OptionHandlerFor(optionHandler->Type())) || OptionHandlerFor(optionHandler->Type()))
return false; return false;
// a running connection may not change and there may only be // a running connection may not change and there may only be
// one handler per option type // one handler per option type
return fOptionHandlers.AddItem(optionHandler); return fOptionHandlers.AddItem(optionHandler);
} }
/*! \brief Removes an option handler, but does not delete it. /*! \brief Removes an option handler, but does not delete it.
NOTE: You can only remove option handlers in \c PPP_DOWN_PHASE. NOTE: You can only remove option handlers in \c PPP_DOWN_PHASE.
*/ */
bool bool
@@ -78,7 +81,7 @@ KPPPLCP::RemoveOptionHandler(KPPPOptionHandler *optionHandler)
if (Interface().Phase() != PPP_DOWN_PHASE) if (Interface().Phase() != PPP_DOWN_PHASE)
return false; return false;
// a running connection may not change // a running connection may not change
return fOptionHandlers.RemoveItem(optionHandler); return fOptionHandlers.RemoveItem(optionHandler);
} }
@@ -87,11 +90,12 @@ KPPPLCP::RemoveOptionHandler(KPPPOptionHandler *optionHandler)
KPPPOptionHandler* KPPPOptionHandler*
KPPPLCP::OptionHandlerAt(int32 index) const KPPPLCP::OptionHandlerAt(int32 index) const
{ {
dprintf("total optionhandler count %ld\n", CountOptionHandlers());
KPPPOptionHandler *optionHandler = fOptionHandlers.ItemAt(index); KPPPOptionHandler *optionHandler = fOptionHandlers.ItemAt(index);
if (optionHandler == fOptionHandlers.GetDefaultItem()) if (optionHandler == fOptionHandlers.GetDefaultItem())
return NULL; return NULL;
return optionHandler; return optionHandler;
} }
@@ -103,14 +107,14 @@ KPPPLCP::OptionHandlerFor(uint8 type, int32 *start) const
// The iteration style in this method is strange C/C++. // The iteration style in this method is strange C/C++.
// Explanation: I use this style because it makes extending all XXXFor // Explanation: I use this style because it makes extending all XXXFor
// methods simpler as that they look very similar, now. // methods simpler as that they look very similar, now.
int32 index = start ? *start : 0; int32 index = start ? *start : 0;
if (index < 0) if (index < 0)
return NULL; return NULL;
KPPPOptionHandler *current = OptionHandlerAt(index); KPPPOptionHandler *current = OptionHandlerAt(index);
for (; current; current = OptionHandlerAt(++index)) { for (; current; current = OptionHandlerAt(++index)) {
if (current->Type() == type) { if (current->Type() == type) {
if (start) if (start)
@@ -118,13 +122,13 @@ KPPPLCP::OptionHandlerFor(uint8 type, int32 *start) const
return current; return current;
} }
} }
return NULL; return NULL;
} }
/*! \brief Adds a new LCP extension. /*! \brief Adds a new LCP extension.
NOTE: You can only add LCP extensions in \c PPP_DOWN_PHASE. NOTE: You can only add LCP extensions in \c PPP_DOWN_PHASE.
*/ */
bool bool
@@ -132,17 +136,17 @@ KPPPLCP::AddLCPExtension(KPPPLCPExtension *lcpExtension)
{ {
if (!lcpExtension || &lcpExtension->Interface() != &Interface()) if (!lcpExtension || &lcpExtension->Interface() != &Interface())
return false; return false;
if (Interface().Phase() != PPP_DOWN_PHASE) if (Interface().Phase() != PPP_DOWN_PHASE)
return false; return false;
// a running connection may not change // a running connection may not change
return fLCPExtensions.AddItem(lcpExtension); return fLCPExtensions.AddItem(lcpExtension);
} }
/*! \brief Removes an LCP extension, but does not delete it. /*! \brief Removes an LCP extension, but does not delete it.
NOTE: You can only remove LCP extensions in \c PPP_DOWN_PHASE. NOTE: You can only remove LCP extensions in \c PPP_DOWN_PHASE.
*/ */
bool bool
@@ -151,7 +155,7 @@ KPPPLCP::RemoveLCPExtension(KPPPLCPExtension *lcpExtension)
if (Interface().Phase() != PPP_DOWN_PHASE) if (Interface().Phase() != PPP_DOWN_PHASE)
return false; return false;
// a running connection may not change // a running connection may not change
return fLCPExtensions.RemoveItem(lcpExtension); return fLCPExtensions.RemoveItem(lcpExtension);
} }
@@ -160,11 +164,12 @@ KPPPLCP::RemoveLCPExtension(KPPPLCPExtension *lcpExtension)
KPPPLCPExtension* KPPPLCPExtension*
KPPPLCP::LCPExtensionAt(int32 index) const KPPPLCP::LCPExtensionAt(int32 index) const
{ {
dprintf("LCPExtension count %ld\n", CountLCPExtensions());
KPPPLCPExtension *lcpExtension = fLCPExtensions.ItemAt(index); KPPPLCPExtension *lcpExtension = fLCPExtensions.ItemAt(index);
if (lcpExtension == fLCPExtensions.GetDefaultItem()) if (lcpExtension == fLCPExtensions.GetDefaultItem())
return NULL; return NULL;
return lcpExtension; return lcpExtension;
} }
@@ -176,14 +181,14 @@ KPPPLCP::LCPExtensionFor(uint8 code, int32 *start) const
// The iteration style in this method is strange C/C++. // The iteration style in this method is strange C/C++.
// Explanation: I use this style because it makes extending all XXXFor // Explanation: I use this style because it makes extending all XXXFor
// methods simpler as that they look very similar, now. // methods simpler as that they look very similar, now.
int32 index = start ? *start : 0; int32 index = start ? *start : 0;
if (index < 0) if (index < 0)
return NULL; return NULL;
KPPPLCPExtension *current = LCPExtensionAt(index); KPPPLCPExtension *current = LCPExtensionAt(index);
for (; current; current = LCPExtensionAt(++index)) { for (; current; current = LCPExtensionAt(++index)) {
if (current->Code() == code) { if (current->Code() == code) {
if (start) if (start)
@@ -191,27 +196,11 @@ KPPPLCP::LCPExtensionFor(uint8 code, int32 *start) const
return current; return current;
} }
} }
return NULL; return NULL;
} }
//! Returns the interface, target, and device overhead.
uint32
KPPPLCP::AdditionalOverhead() const
{
uint32 overhead = Interface().Overhead();
if (Target())
overhead += Target()->Overhead();
if (Interface().Device())
overhead += Interface().Device()->Overhead();
return overhead;
}
//! Always returns \c true. //! Always returns \c true.
bool bool
KPPPLCP::Up() KPPPLCP::Up()
@@ -230,7 +219,7 @@ KPPPLCP::Down()
//! Sends a packet to the target (if there is one) or to the interface. //! Sends a packet to the target (if there is one) or to the interface.
status_t status_t
KPPPLCP::Send(struct mbuf *packet, uint16 protocolNumber) KPPPLCP::Send(net_buffer *packet, uint16 protocolNumber)
{ {
if (Target()) if (Target())
return Target()->Send(packet, PPP_LCP_PROTOCOL); return Target()->Send(packet, PPP_LCP_PROTOCOL);
@@ -241,39 +230,32 @@ KPPPLCP::Send(struct mbuf *packet, uint16 protocolNumber)
//! Decodes the LCP packet and passes it to the KPPPStateMachine or an LCP extension. //! Decodes the LCP packet and passes it to the KPPPStateMachine or an LCP extension.
status_t status_t
KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber) KPPPLCP::Receive(net_buffer *packet, uint16 protocolNumber)
{ {
if (!packet) if (!packet)
return B_ERROR; return B_ERROR;
if (protocolNumber != PPP_LCP_PROTOCOL) { if (protocolNumber != PPP_LCP_PROTOCOL) {
ERROR("KPPPLCP::Receive(): wrong protocol number!\n"); ERROR("KPPPLCP::Receive(): wrong protocol number!\n");
return PPP_UNHANDLED; return PPP_UNHANDLED;
} }
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*); NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
if (bufferHeader.Status() < B_OK)
return bufferHeader.Status();
ppp_lcp_packet &data = bufferHeader.Data();
// remove padding // remove padding
int32 length = packet->m_len;
if (packet->m_flags & M_PKTHDR) net_buffer *copy = gBufferModule->duplicate(packet);
length = packet->m_pkthdr.len;
length -= ntohs(data->length); if (ntohs(data.length) < 4)
if (length)
m_adj(packet, -length);
struct mbuf *copy = m_gethdr(MT_DATA);
if (copy) {
copy->m_data += AdditionalOverhead();
copy->m_pkthdr.len = copy->m_len = packet->m_len;
memcpy(copy->m_data, packet->m_data, copy->m_len);
}
if (ntohs(data->length) < 4)
return B_ERROR; return B_ERROR;
bool handled = true; bool handled = true;
switch (data->code) { switch (data.code) {
case PPP_CONFIGURE_REQUEST: case PPP_CONFIGURE_REQUEST:
StateMachine().RCREvent(packet); StateMachine().RCREvent(packet);
break; break;
@@ -310,43 +292,43 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
break; break;
default: default:
m_freem(packet); // gBufferModule->free(packet);
handled = false; handled = false;
} }
packet = copy; packet = copy;
if (!packet) if (!packet)
return handled ? B_OK : B_ERROR; return handled ? B_OK : B_ERROR;
status_t result = B_OK; status_t result = B_OK;
// Try to find LCP extensions that can handle this code. // Try to find LCP extensions that can handle this code.
// We must duplicate the packet in order to ask all handlers. // We must duplicate the packet in order to ask all handlers.
int32 index = 0; int32 index = 0;
KPPPLCPExtension *lcpExtension = LCPExtensionFor(data->code, &index); KPPPLCPExtension *lcpExtension = LCPExtensionFor(data.code, &index);
for (; lcpExtension; lcpExtension = LCPExtensionFor(data->code, &(++index))) { for (; lcpExtension; lcpExtension = LCPExtensionFor(data.code, &(++index))) {
if (!lcpExtension->IsEnabled()) if (!lcpExtension->IsEnabled())
continue; continue;
result = lcpExtension->Receive(packet, data->code); result = lcpExtension->Receive(packet, data.code);
// check return value and return it on error // check return value and return it on error
if (result == B_OK) if (result == B_OK)
handled = true; handled = true;
else if (result != PPP_UNHANDLED) { else if (result != PPP_UNHANDLED) {
m_freem(packet); gBufferModule->free(packet);
return result; return result;
} }
} }
if (!handled) { if (!handled) {
StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT); StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT);
return PPP_REJECTED; return PPP_REJECTED;
} }
m_freem(packet); gBufferModule->free(packet);
return result; return result;
} }
@@ -356,7 +338,7 @@ void
KPPPLCP::Pulse() KPPPLCP::Pulse()
{ {
StateMachine().TimerEvent(); StateMachine().TimerEvent();
for (int32 index = 0; index < CountLCPExtensions(); index++) for (int32 index = 0; index < CountLCPExtensions(); index++)
LCPExtensionAt(index)->Pulse(); LCPExtensionAt(index)->Pulse();
} }
@@ -58,6 +58,7 @@ KPPPLCPExtension::InitCheck() const
status_t status_t
KPPPLCPExtension::Control(uint32 op, void *data, size_t length) KPPPLCPExtension::Control(uint32 op, void *data, size_t length)
{ {
dprintf("KPPPLCPExtension::Control\n");
switch (op) { switch (op) {
case PPPC_GET_SIMPLE_HANDLER_INFO: case PPPC_GET_SIMPLE_HANDLER_INFO:
{ {
@@ -5,7 +5,7 @@
/*! \class KPPPLayer /*! \class KPPPLayer
\brief An abstract layer that can encapsulate/send and receive packets. \brief An abstract layer that can encapsulate/send and receive packets.
All packet handlers should derive from this class. It does not define a protocol All packet handlers should derive from this class. It does not define a protocol
number like KPPPProtocol does. It only has a header overhead and an encapsulation number like KPPPProtocol does. It only has a header overhead and an encapsulation
level that is used to determine the order at which the packets get encapsulated level that is used to determine the order at which the packets get encapsulated
@@ -19,13 +19,15 @@
#include <KPPPLayer.h> #include <KPPPLayer.h>
#include <net_buffer.h>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <core_funcs.h>
extern net_buffer_module_info *gBufferModule;
/*! \brief Creates a new layer. /*! \brief Creates a new layer.
If an error occurs in the constructor you should set \c fInitStatus. If an error occurs in the constructor you should set \c fInitStatus.
*/ */
KPPPLayer::KPPPLayer(const char *name, ppp_level level, uint32 overhead) KPPPLayer::KPPPLayer(const char *name, ppp_level level, uint32 overhead)
@@ -56,11 +58,11 @@ KPPPLayer::InitCheck() const
//! Sends a packet to the next layer in the chain. //! Sends a packet to the next layer in the chain.
status_t status_t
KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const KPPPLayer::SendToNext(net_buffer *packet, uint16 protocolNumber) const
{ {
if (!packet) if (!packet)
return B_ERROR; return B_ERROR;
// Find the next possible handler for this packet. // Find the next possible handler for this packet.
// Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything. // Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything.
if (Next()) { if (Next()) {
@@ -70,14 +72,14 @@ KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
return Next()->SendToNext(packet, protocolNumber); return Next()->SendToNext(packet, protocolNumber);
} else { } else {
ERROR("KPPPLayer: SendToNext() failed because there is no next handler!\n"); ERROR("KPPPLayer: SendToNext() failed because there is no next handler!\n");
m_freem(packet); gBufferModule->free(packet);
return B_ERROR; return B_ERROR;
} }
} }
/*! \brief You may override this for periodic tasks. /*! \brief You may override this for periodic tasks.
This method gets called every \c PPP_PULSE_RATE microseconds. This method gets called every \c PPP_PULSE_RATE microseconds.
*/ */
void void
@@ -92,7 +94,7 @@ void
KPPPLayer::SetName(const char *name) KPPPLayer::SetName(const char *name)
{ {
free(fName); free(fName);
if (name) if (name)
fName = strdup(name); fName = strdup(name);
else else
@@ -60,6 +60,7 @@ KPPPOptionHandler::InitCheck() const
status_t status_t
KPPPOptionHandler::Control(uint32 op, void *data, size_t length) KPPPOptionHandler::Control(uint32 op, void *data, size_t length)
{ {
dprintf("KPPPOptionHandler::Control\n");
switch (op) { switch (op) {
case PPPC_GET_SIMPLE_HANDLER_INFO: case PPPC_GET_SIMPLE_HANDLER_INFO:
{ {
@@ -9,7 +9,9 @@
#include <KPPPReportManager.h> #include <KPPPReportManager.h>
#include <LockerHelper.h> #include <lock.h>
#include <util/AutoLock.h>
#include <KPPPUtils.h> #include <KPPPUtils.h>
@@ -30,10 +32,10 @@ report_sender_thread(void *data)
/*! \brief Constructor. /*! \brief Constructor.
\param lock The BLocker that should be used by this report manager. \param lock The BLocker that should be used by this report manager.
*/ */
KPPPReportManager::KPPPReportManager(BLocker& lock) KPPPReportManager::KPPPReportManager(mutex& lock)
: fLock(lock) : fLock(lock)
{ {
} }
@@ -48,10 +50,10 @@ KPPPReportManager::~KPPPReportManager()
/*! \brief Send the given report message to the given thread. /*! \brief Send the given report message to the given thread.
\param thread The report receiver. \param thread The report receiver.
\param report The report message. \param report The report message.
\return \c false on error. \return \c false on error.
*/ */
bool bool
@@ -59,7 +61,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
{ {
if (!report) if (!report)
return false; return false;
if (thread == find_thread(NULL)) { if (thread == find_thread(NULL)) {
report_sender_info *info = new report_sender_info; report_sender_info *info = new report_sender_info;
info->thread = thread; info->thread = thread;
@@ -68,7 +70,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
B_NORMAL_PRIORITY, info)); B_NORMAL_PRIORITY, info));
return true; return true;
} }
send_data_with_timeout(thread, PPP_REPORT_CODE, &report, sizeof(report), send_data_with_timeout(thread, PPP_REPORT_CODE, &report, sizeof(report),
PPP_REPORT_TIMEOUT); PPP_REPORT_TIMEOUT);
return true; return true;
@@ -76,7 +78,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
/*! \brief Requests report messages of a given \a type. /*! \brief Requests report messages of a given \a type.
\param type The type of report. \param type The type of report.
\param thread The receiver thread. \param thread The receiver thread.
\param flags Optional report flags. See \c ppp_report_flags for more information. \param flags Optional report flags. See \c ppp_report_flags for more information.
@@ -87,14 +89,14 @@ KPPPReportManager::EnableReports(ppp_report_type type, thread_id thread,
{ {
if (thread < 0 || type == PPP_ALL_REPORTS) if (thread < 0 || type == PPP_ALL_REPORTS)
return; return;
LockerHelper locker(fLock); MutexLocker locker(fLock);
ppp_report_request *request = new ppp_report_request; ppp_report_request *request = new ppp_report_request;
request->type = type; request->type = type;
request->thread = thread; request->thread = thread;
request->flags = flags; request->flags = flags;
fReportRequests.AddItem(request); fReportRequests.AddItem(request);
} }
@@ -105,21 +107,21 @@ KPPPReportManager::DisableReports(ppp_report_type type, thread_id thread)
{ {
if (thread < 0) if (thread < 0)
return; return;
LockerHelper locker(fLock); MutexLocker locker(fLock);
ppp_report_request *request; ppp_report_request *request;
for (int32 i = 0; i < fReportRequests.CountItems(); i++) { for (int32 i = 0; i < fReportRequests.CountItems(); i++) {
request = fReportRequests.ItemAt(i); request = fReportRequests.ItemAt(i);
if (request->thread != thread) if (request->thread != thread)
continue; continue;
if (request->type == type || type == PPP_ALL_REPORTS) if (request->type == type || type == PPP_ALL_REPORTS)
fReportRequests.RemoveItem(request); fReportRequests.RemoveItem(request);
} }
// empty message queue // empty message queue
while (has_data(thread)) { while (has_data(thread)) {
thread_id sender; thread_id sender;
@@ -134,32 +136,32 @@ KPPPReportManager::DoesReport(ppp_report_type type, thread_id thread)
{ {
if (thread < 0) if (thread < 0)
return false; return false;
LockerHelper locker(fLock); MutexLocker locker(fLock);
ppp_report_request *request; ppp_report_request *request;
for (int32 i = 0; i < fReportRequests.CountItems(); i++) { for (int32 i = 0; i < fReportRequests.CountItems(); i++) {
request = fReportRequests.ItemAt(i); request = fReportRequests.ItemAt(i);
if (request->thread == thread && request->type == type) if (request->thread == thread && request->type == type)
return true; return true;
} }
return false; return false;
} }
/*! \brief Send out report messages to all requestors. /*! \brief Send out report messages to all requestors.
You may append additional data to the report messages. The data length may not be You may append additional data to the report messages. The data length may not be
greater than \c PPP_REPORT_DATA_LIMIT. greater than \c PPP_REPORT_DATA_LIMIT.
\param type The report type. \param type The report type.
\param code The report code belonging to the report type. \param code The report code belonging to the report type.
\param data Additional data. \param data Additional data.
\param length Length of the data. \param length Length of the data.
\return \c false on error. \return \c false on error.
*/ */
bool bool
@@ -167,44 +169,44 @@ KPPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 le
{ {
TRACE("KPPPReportManager: Report(type=%d code=%ld length=%ld) to %ld receivers\n", TRACE("KPPPReportManager: Report(type=%d code=%ld length=%ld) to %ld receivers\n",
type, code, length, fReportRequests.CountItems()); type, code, length, fReportRequests.CountItems());
if (length > PPP_REPORT_DATA_LIMIT) if (length > PPP_REPORT_DATA_LIMIT)
return false; return false;
if (fReportRequests.CountItems() == 0) if (fReportRequests.CountItems() == 0)
return true; return true;
if (!data) if (!data)
length = 0; length = 0;
LockerHelper locker(fLock); MutexLocker locker(fLock);
status_t result; status_t result;
thread_id me = find_thread(NULL); thread_id me = find_thread(NULL);
ppp_report_packet report; ppp_report_packet report;
report.type = type; report.type = type;
report.code = code; report.code = code;
report.length = length; report.length = length;
memcpy(report.data, data, length); memcpy(report.data, data, length);
ppp_report_request *request; ppp_report_request *request;
for (int32 index = 0; index < fReportRequests.CountItems(); index++) { for (int32 index = 0; index < fReportRequests.CountItems(); index++) {
request = fReportRequests.ItemAt(index); request = fReportRequests.ItemAt(index);
// do not send to yourself // do not send to yourself
if (request->thread == me) if (request->thread == me)
continue; continue;
result = send_data_with_timeout(request->thread, PPP_REPORT_CODE, &report, result = send_data_with_timeout(request->thread, PPP_REPORT_CODE, &report,
sizeof(report), PPP_REPORT_TIMEOUT); sizeof(report), PPP_REPORT_TIMEOUT);
#if DEBUG #if DEBUG
if (result == B_TIMED_OUT) if (result == B_TIMED_OUT)
TRACE("KPPPReportManager::Report(): timed out sending\n"); TRACE("KPPPReportManager::Report(): timed out sending\n");
#endif #endif
if (result == B_BAD_THREAD_ID || result == B_NO_MEMORY if (result == B_BAD_THREAD_ID || result == B_NO_MEMORY
|| request->flags & PPP_REMOVE_AFTER_REPORT) { || request->flags & PPP_REMOVE_AFTER_REPORT) {
fReportRequests.RemoveItem(request); fReportRequests.RemoveItem(request);
@@ -212,6 +214,6 @@ KPPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 le
continue; continue;
} }
} }
return true; return true;
} }
File diff suppressed because it is too large Load Diff
@@ -7,8 +7,7 @@
#define _K_PPP_CONFIGURE_PACKET__H #define _K_PPP_CONFIGURE_PACKET__H
#include <TemplateList.h> #include <TemplateList.h>
#include <net_buffer.h>
struct mbuf;
//! An abstract configure item. //! An abstract configure item.
typedef struct ppp_configure_item { typedef struct ppp_configure_item {
@@ -29,7 +28,7 @@ class KPPPConfigurePacket {
public: public:
KPPPConfigurePacket(uint8 code); KPPPConfigurePacket(uint8 code);
KPPPConfigurePacket(struct mbuf *packet); KPPPConfigurePacket(net_buffer *packet);
~KPPPConfigurePacket(); ~KPPPConfigurePacket();
bool SetCode(uint8 code); bool SetCode(uint8 code);
@@ -52,8 +51,8 @@ class KPPPConfigurePacket {
ppp_configure_item *ItemAt(int32 index) const; ppp_configure_item *ItemAt(int32 index) const;
ppp_configure_item *ItemWithType(uint8 type) const; ppp_configure_item *ItemWithType(uint8 type) const;
struct mbuf *ToMbuf(uint32 MRU, uint32 reserve = 0); net_buffer *ToNetBuffer(uint32 MRU);
// the user is responsible for freeing the mbuf // the user is responsible for freeing the net_buffer
private: private:
uint8 fCode, fID; uint8 fCode, fID;
@@ -9,6 +9,8 @@
#include <KPPPDefs.h> #include <KPPPDefs.h>
#include <KPPPLayer.h> #include <KPPPLayer.h>
#include <net_buffer.h>
#ifndef _K_PPP_INTERFACE__H #ifndef _K_PPP_INTERFACE__H
#include <KPPPInterface.h> #include <KPPPInterface.h>
#endif #endif
@@ -96,8 +98,8 @@ class KPPPDevice : public KPPPLayer {
This should enqueue the packet and return immediately (never block). This should enqueue the packet and return immediately (never block).
The device is responsible for freeing the packet by calling \c m_freem(). The device is responsible for freeing the packet by calling \c m_freem().
*/ */
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0; virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
protected: protected:
//! Use this to set the device's maximum transfer unit (in bytes). //! Use this to set the device's maximum transfer unit (in bytes).
@@ -30,6 +30,12 @@
#include <TemplateList.h> #include <TemplateList.h>
#include <net_buffer.h>
#include <net_device.h>
#include <lock.h>
#include <util/AutoLock.h>
class KPPPDevice; class KPPPDevice;
class KPPPProtocol; class KPPPProtocol;
class KPPPOptionHandler; class KPPPOptionHandler;
@@ -48,6 +54,8 @@ class KPPPInterface : public KPPPLayer {
KPPPInterface(const KPPPInterface& copy); KPPPInterface(const KPPPInterface& copy);
KPPPInterface& operator= (const KPPPInterface& copy); KPPPInterface& operator= (const KPPPInterface& copy);
public:
// we should set to private after finishing test
// only PPPManager may construct us! // only PPPManager may construct us!
KPPPInterface(const char *name, ppp_interface_entry *entry, KPPPInterface(const char *name, ppp_interface_entry *entry,
ppp_interface_id ID, const driver_settings *settings, ppp_interface_id ID, const driver_settings *settings,
@@ -75,8 +83,8 @@ class KPPPInterface : public KPPPLayer {
{ return fLCP; } { return fLCP; }
//! Returns the interfac's ifnet structure that is exported to the netstack. //! Returns the interfac's ifnet structure that is exported to the netstack.
struct ifnet *Ifnet() const net_device *Ifnet() const
{ return fIfnet; } { return fIfnet; }
const char *Username() const; const char *Username() const;
const char *Password() const; const char *Password() const;
@@ -220,11 +228,11 @@ class KPPPInterface : public KPPPLayer {
virtual bool IsAllowedToSend() const; virtual bool IsAllowedToSend() const;
// always returns true // always returns true
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber); virtual status_t Send(net_buffer *packet, uint16 protocolNumber);
// sends the packet to the next handler (normally the device) // sends the packet to the next handler (normally the device)
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
status_t ReceiveFromDevice(struct mbuf *packet); status_t ReceiveFromDevice(net_buffer *packet);
// This must not block KPPPDevice::Send()! // This must not block KPPPDevice::Send()!
void Pulse(); void Pulse();
@@ -255,7 +263,7 @@ class KPPPInterface : public KPPPLayer {
ppp_interface_id fID; ppp_interface_id fID;
// the manager assigns an ID to every interface // the manager assigns an ID to every interface
driver_settings *fSettings; driver_settings *fSettings;
struct ifnet *fIfnet; net_device *fIfnet;
char *fUsername, *fPassword; char *fUsername, *fPassword;
@@ -288,7 +296,7 @@ class KPPPInterface : public KPPPLayer {
KPPPStateMachine fStateMachine; KPPPStateMachine fStateMachine;
KPPPLCP fLCP; KPPPLCP fLCP;
KPPPReportManager fReportManager; KPPPReportManager fReportManager;
BLocker& fLock; mutex& fLock;
int32 fDeleteCounter; int32 fDeleteCounter;
}; };
@@ -20,6 +20,9 @@
#include <KPPPStateMachine.h> #include <KPPPStateMachine.h>
#endif #endif
#include <net_buffer.h>
#include <NetBufferUtilities.h>
class KPPPLCPExtension; class KPPPLCPExtension;
class KPPPOptionHandler; class KPPPOptionHandler;
@@ -79,15 +82,12 @@ class KPPPLCP : public KPPPProtocol {
KPPPProtocol *Target() const KPPPProtocol *Target() const
{ return fTarget; } { return fTarget; }
uint32 AdditionalOverhead() const;
// the overhead caused by the target, the device, and the interface
virtual bool Up(); virtual bool Up();
virtual bool Down(); virtual bool Down();
virtual status_t Send(struct mbuf *packet, virtual status_t Send(net_buffer *packet,
uint16 protocolNumber = PPP_LCP_PROTOCOL); uint16 protocolNumber = PPP_LCP_PROTOCOL);
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber); virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
virtual void Pulse(); virtual void Pulse();
@@ -51,7 +51,7 @@ class KPPPLCPExtension {
// called by netstack (forwarded by KPPPInterface) // called by netstack (forwarded by KPPPInterface)
//! Must be overridden. Called when an LCP packet with your code is received. //! Must be overridden. Called when an LCP packet with your code is received.
virtual status_t Receive(struct mbuf *packet, uint8 code) = 0; virtual status_t Receive(net_buffer *packet, uint8 code) = 0;
virtual void Reset(); virtual void Reset();
virtual void Pulse(); virtual void Pulse();
@@ -8,6 +8,7 @@
#include <KPPPDefs.h> #include <KPPPDefs.h>
#include <net_buffer.h>
class KPPPLayer { class KPPPLayer {
protected: protected:
@@ -48,11 +49,11 @@ class KPPPLayer {
virtual bool IsAllowedToSend() const = 0; virtual bool IsAllowedToSend() const = 0;
//! Send a packet with the given protocol number. //! Send a packet with the given protocol number.
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0; virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
//! Receive a packet with the given protocol number. //! Receive a packet with the given protocol number.
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0; virtual status_t Receive(net_buffer *packet, uint16 protocolNumber) = 0;
status_t SendToNext(struct mbuf *packet, uint16 protocolNumber) const; status_t SendToNext(net_buffer *packet, uint16 protocolNumber) const;
// send the packet to the next layer // send the packet to the next layer
virtual void Pulse(); virtual void Pulse();
@@ -6,12 +6,12 @@
#ifndef _K_PPP_MANAGER__H #ifndef _K_PPP_MANAGER__H
#define _K_PPP_MANAGER__H #define _K_PPP_MANAGER__H
#include "net_module.h" #include <module.h>
#include <net_device.h>
#include <PPPControl.h> #include <PPPControl.h>
#include <PPPReportDefs.h> #include <PPPReportDefs.h>
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/KPPPManager/v1"
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "interfaces/ppp"
#define PPP_UNDEFINED_INTERFACE_ID 0 #define PPP_UNDEFINED_INTERFACE_ID 0
// CreateInterface() returns this value on failure // CreateInterface() returns this value on failure
@@ -34,8 +34,7 @@ typedef struct ppp_interface_entry {
deletes them when they are not needed anymore. deletes them when they are not needed anymore.
*/ */
typedef struct ppp_interface_module_info { typedef struct ppp_interface_module_info {
kernel_net_module_info knminfo; struct module_info info;
//!< Exports needed network module functions.
ppp_interface_id (*CreateInterface)(const driver_settings *settings, ppp_interface_id (*CreateInterface)(const driver_settings *settings,
ppp_interface_id parentID); ppp_interface_id parentID);
@@ -46,7 +45,9 @@ typedef struct ppp_interface_module_info {
bool (*RemoveInterface)(ppp_interface_id ID); bool (*RemoveInterface)(ppp_interface_id ID);
// remove the interface from database (make sure you can delete it yourself!) // remove the interface from database (make sure you can delete it yourself!)
ifnet *(*RegisterInterface)(ppp_interface_id ID); net_device *(*RegisterInterface)(ppp_interface_id ID);
KPPPInterface *(*GetInterface)(ppp_interface_id ID);
// for accessing KPPPInterface directly
bool (*UnregisterInterface)(ppp_interface_id ID); bool (*UnregisterInterface)(ppp_interface_id ID);
status_t (*ControlInterface)(ppp_interface_id ID, uint32 op, void *data, status_t (*ControlInterface)(ppp_interface_id ID, uint32 op, void *data,
@@ -105,9 +105,9 @@ class KPPPProtocol : public KPPPLayer {
virtual bool IsAllowedToSend() const; virtual bool IsAllowedToSend() const;
//! Encapsulate the packet with the given protocol number. //! Encapsulate the packet with the given protocol number.
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0; virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
//! Receive a packet with the given protocol number. //! Receive a packet with the given protocol number.
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0; virtual status_t Receive(net_buffer *packet, uint16 protocolNumber) = 0;
protected: protected:
//! \brief Requests Up() to be called. //! \brief Requests Up() to be called.
@@ -13,10 +13,13 @@
#include <TemplateList.h> #include <TemplateList.h>
#include <lock.h>
#include <util/AutoLock.h>
class KPPPReportManager { class KPPPReportManager {
public: public:
KPPPReportManager(BLocker& lock); KPPPReportManager(mutex& lock);
~KPPPReportManager(); ~KPPPReportManager();
static bool SendReport(thread_id thread, const ppp_report_packet *report); static bool SendReport(thread_id thread, const ppp_report_packet *report);
@@ -30,7 +33,7 @@ class KPPPReportManager {
// returns false if reply was bad (or an error occured) // returns false if reply was bad (or an error occured)
private: private:
BLocker& fLock; mutex& fLock;
TemplateList<ppp_report_request*> fReportRequests; TemplateList<ppp_report_request*> fReportRequests;
}; };
@@ -14,7 +14,8 @@ class KPPPProtocol;
#include <KPPPInterface.h> #include <KPPPInterface.h>
#endif #endif
#include <Locker.h> #include <lock.h>
#include <util/AutoLock.h>
class PPPManager; class PPPManager;
class KPPPInterface; class KPPPInterface;
@@ -30,7 +31,7 @@ class KPPPStateMachine {
// may only be constructed/destructed by KPPPInterface // may only be constructed/destructed by KPPPInterface
KPPPStateMachine(KPPPInterface& interface); KPPPStateMachine(KPPPInterface& interface);
~KPPPStateMachine(); ~KPPPStateMachine();
// copies are not allowed! // copies are not allowed!
KPPPStateMachine(const KPPPStateMachine& copy); KPPPStateMachine(const KPPPStateMachine& copy);
KPPPStateMachine& operator= (const KPPPStateMachine& copy); KPPPStateMachine& operator= (const KPPPStateMachine& copy);
@@ -42,28 +43,28 @@ class KPPPStateMachine {
//! Returns the LCP protocol object belonging to this state machine. //! Returns the LCP protocol object belonging to this state machine.
KPPPLCP& LCP() const KPPPLCP& LCP() const
{ return fLCP; } { return fLCP; }
//! Returns the current state as defined in RFC 1661. //! Returns the current state as defined in RFC 1661.
ppp_state State() const ppp_state State() const
{ return fState; } { return fState; }
//! Returns the internal phase. //! Returns the internal phase.
ppp_phase Phase() const ppp_phase Phase() const
{ return fPhase; } { return fPhase; }
uint8 NextID(); uint8 NextID();
//! Sets our packets' magic number. Used by Link-Quality-Monitoring. //! Sets our packets' magic number. Used by Link-Quality-Monitoring.
void SetMagicNumber(uint32 magicNumber) void SetMagicNumber(uint32 magicNumber)
{ fMagicNumber = magicNumber; } { fMagicNumber = magicNumber; }
//! Returns our packets' magic number. //! Returns our packets' magic number.
uint32 MagicNumber() const uint32 MagicNumber() const
{ return fMagicNumber; } { return fMagicNumber; }
// public actions // public actions
bool Reconfigure(); bool Reconfigure();
bool SendEchoRequest(); bool SendEchoRequest();
bool SendDiscardRequest(); bool SendDiscardRequest();
// public events: // public events:
// NOTE: Local/PeerAuthenticationAccepted/Denied MUST be called before // NOTE: Local/PeerAuthenticationAccepted/Denied MUST be called before
// Up(Failed)/DownEvent in order to allow changing the configuration of // Up(Failed)/DownEvent in order to allow changing the configuration of
@@ -77,7 +78,7 @@ class KPPPStateMachine {
//! Returns our local authentication status. //! Returns our local authentication status.
ppp_authentication_status LocalAuthenticationStatus() const ppp_authentication_status LocalAuthenticationStatus() const
{ return fLocalAuthenticationStatus; } { return fLocalAuthenticationStatus; }
void PeerAuthenticationRequested(); void PeerAuthenticationRequested();
void PeerAuthenticationAccepted(const char *name); void PeerAuthenticationAccepted(const char *name);
void PeerAuthenticationDenied(const char *name); void PeerAuthenticationDenied(const char *name);
@@ -87,17 +88,17 @@ class KPPPStateMachine {
//! Returns the peer's authentication status. //! Returns the peer's authentication status.
ppp_authentication_status PeerAuthenticationStatus() const ppp_authentication_status PeerAuthenticationStatus() const
{ return fPeerAuthenticationStatus; } { return fPeerAuthenticationStatus; }
// sub-interface events // sub-interface events
void UpFailedEvent(KPPPInterface& interface); void UpFailedEvent(KPPPInterface& interface);
void UpEvent(KPPPInterface& interface); void UpEvent(KPPPInterface& interface);
void DownEvent(KPPPInterface& interface); void DownEvent(KPPPInterface& interface);
// protocol events // protocol events
void UpFailedEvent(KPPPProtocol *protocol); void UpFailedEvent(KPPPProtocol *protocol);
void UpEvent(KPPPProtocol *protocol); void UpEvent(KPPPProtocol *protocol);
void DownEvent(KPPPProtocol *protocol); void DownEvent(KPPPProtocol *protocol);
// device events // device events
bool TLSNotify(); bool TLSNotify();
bool TLFNotify(); bool TLFNotify();
@@ -109,30 +110,30 @@ class KPPPStateMachine {
// private StateMachine methods // private StateMachine methods
void NewState(ppp_state next); void NewState(ppp_state next);
void NewPhase(ppp_phase next); void NewPhase(ppp_phase next);
// private events // private events
void OpenEvent(); void OpenEvent();
void ContinueOpenEvent(); void ContinueOpenEvent();
void CloseEvent(); void CloseEvent();
void TOGoodEvent(); void TOGoodEvent();
void TOBadEvent(); void TOBadEvent();
void RCRGoodEvent(struct mbuf *packet); void RCRGoodEvent(net_buffer *packet);
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject); void RCRBadEvent(net_buffer *nak, net_buffer *reject);
void RCAEvent(struct mbuf *packet); void RCAEvent(net_buffer *packet);
void RCNEvent(struct mbuf *packet); void RCNEvent(net_buffer *packet);
void RTREvent(struct mbuf *packet); void RTREvent(net_buffer *packet);
void RTAEvent(struct mbuf *packet); void RTAEvent(net_buffer *packet);
void RUCEvent(struct mbuf *packet, uint16 protocolNumber, void RUCEvent(net_buffer *packet, uint16 protocolNumber,
uint8 code = PPP_PROTOCOL_REJECT); uint8 code = PPP_PROTOCOL_REJECT);
void RXJGoodEvent(struct mbuf *packet); void RXJGoodEvent(net_buffer *packet);
void RXJBadEvent(struct mbuf *packet); void RXJBadEvent(net_buffer *packet);
void RXREvent(struct mbuf *packet); void RXREvent(net_buffer *packet);
// general events (for Good/Bad events) // general events (for Good/Bad events)
void TimerEvent(); void TimerEvent();
void RCREvent(struct mbuf *packet); void RCREvent(net_buffer *packet);
void RXJEvent(struct mbuf *packet); void RXJEvent(net_buffer *packet);
// actions // actions
void IllegalEvent(ppp_event event); void IllegalEvent(ppp_event event);
void ThisLayerUp(); void ThisLayerUp();
@@ -142,42 +143,42 @@ class KPPPStateMachine {
void InitializeRestartCount(); void InitializeRestartCount();
void ZeroRestartCount(); void ZeroRestartCount();
bool SendConfigureRequest(); bool SendConfigureRequest();
bool SendConfigureAck(struct mbuf *packet); bool SendConfigureAck(net_buffer *packet);
bool SendConfigureNak(struct mbuf *packet); bool SendConfigureNak(net_buffer *packet);
bool SendTerminateRequest(); bool SendTerminateRequest();
bool SendTerminateAck(struct mbuf *request = NULL); bool SendTerminateAck(net_buffer *request = NULL);
bool SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code); bool SendCodeReject(net_buffer *packet, uint16 protocolNumber, uint8 code);
bool SendEchoReply(struct mbuf *request); bool SendEchoReply(net_buffer *request);
void BringProtocolsUp(); void BringProtocolsUp();
uint32 BringPhaseUp(); uint32 BringPhaseUp();
void DownProtocols(); void DownProtocols();
void ResetLCPHandlers(); void ResetLCPHandlers();
private: private:
KPPPInterface& fInterface; KPPPInterface& fInterface;
KPPPLCP& fLCP; KPPPLCP& fLCP;
ppp_state fState; ppp_state fState;
ppp_phase fPhase; ppp_phase fPhase;
vint32 fID; int32 fID;
uint32 fMagicNumber; uint32 fMagicNumber;
int32 fLastConnectionReportCode; int32 fLastConnectionReportCode;
ppp_authentication_status fLocalAuthenticationStatus, ppp_authentication_status fLocalAuthenticationStatus,
fPeerAuthenticationStatus; fPeerAuthenticationStatus;
char *fLocalAuthenticationName, *fPeerAuthenticationName; char *fLocalAuthenticationName, *fPeerAuthenticationName;
// counters and timers // counters and timers
int32 fMaxRequest, fMaxTerminate, fMaxNak; int32 fMaxRequest, fMaxTerminate, fMaxNak;
int32 fRequestCounter, fTerminateCounter, fNakCounter; int32 fRequestCounter, fTerminateCounter, fNakCounter;
uint8 fRequestID, fTerminateID, fEchoID; uint8 fRequestID, fTerminateID, fEchoID;
// the ID we used for the last configure/terminate/echo request // the ID we used for the last configure/terminate/echo request
bigtime_t fNextTimeout; bigtime_t fNextTimeout;
BLocker fLock; mutex fLock;
}; };
@@ -11,6 +11,76 @@
#include <PPPDefs.h> #include <PPPDefs.h>
#define IF_NAMESIZE 32
// copied from if.h
struct control_net_module_args {
char ifr_name[IF_NAMESIZE];
const char* name;
uint32 op;
void* data;
size_t length;
// union {
// struct sockaddr ifr_addr;
// struct sockaddr ifr_dstaddr;
// struct sockaddr ifr_broadaddr;
// struct sockaddr ifr_mask;
// struct ifreq_stats ifr_stats;
// struct route_entry ifr_route;
// int ifr_flags;
// int ifr_index;
// int ifr_metric;
// int ifr_mtu;
// int ifr_media;
// int ifr_type;
// int ifr_reqcap;
// int ifr_count;
// uint8_t* ifr_data;
// };
};
// copied from libppp
enum {
// Paranoia mode: be far away of B_DEVICE_OP_CODES_END opcodes!!!
// You never know what another device driver ioctl() will do
// if think our NET_STACK_* is in fact his DO_RISKY_BUSINESS opcode, or whatever...
NET_IOCTL_BASE = 0xbe230000,
NET_STACK_IOCTL_BASE = NET_IOCTL_BASE + 0x200
};
enum {
NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args *
NET_STACK_BIND, // sockaddr_args *
NET_STACK_RECVFROM, // struct msghdr *
NET_STACK_RECV, // transfer_args *
NET_STACK_SENDTO, // struct msghdr *
NET_STACK_SEND, // transfer_args *
NET_STACK_LISTEN, // int_args * (value = backlog)
NET_STACK_ACCEPT, // sockaddr_args *
NET_STACK_CONNECT, // sockaddr_args *
NET_STACK_SHUTDOWN, // int_args * (value = how)
NET_STACK_GETSOCKOPT, // sockopt_args *
NET_STACK_SETSOCKOPT, // sockopt_args *
NET_STACK_GETSOCKNAME, // sockaddr_args *
NET_STACK_GETPEERNAME, // sockaddr_args *
NET_STACK_SYSCTL, // sysctl_args *
NET_STACK_SELECT, // select_args *
NET_STACK_DESELECT, // select_args *
NET_STACK_GET_COOKIE, // void **
NET_STACK_STOP,
NET_STACK_NOTIFY_SOCKET_EVENT, // notify_socket_event_args * (userland stack only)
NET_STACK_CONTROL_NET_MODULE,
NET_STACK_IOCTL_MAX
};
// various constants // various constants
#define PPP_HANDLER_NAME_LENGTH_LIMIT 63 #define PPP_HANDLER_NAME_LENGTH_LIMIT 63
// if the name is longer than this value it will be truncated to fit the structure // if the name is longer than this value it will be truncated to fit the structure
@@ -10,8 +10,6 @@
#include <directories.h> #include <directories.h>
#include "net_module.h"
typedef uint32 ppp_interface_id; typedef uint32 ppp_interface_id;
@@ -37,7 +35,8 @@ typedef uint32 ppp_interface_id;
#define PPP_SERVER_MODE_VALUE "Server" #define PPP_SERVER_MODE_VALUE "Server"
// path defines // path defines
#define PPP_MODULES_PATH NETWORK_MODULES_ROOT "ppp" #define NETWORK_MODULES_ROOT "network"
#define PPP_MODULES_PATH NETWORK_MODULES_ROOT "/ppp"
#define PTP_INTERFACE_SETTINGS_PATH \ #define PTP_INTERFACE_SETTINGS_PATH \
kUserSettingsDirectory "/kernel/drivers/ptpnet" kUserSettingsDirectory "/kernel/drivers/ptpnet"
// TODO: should be: /etc/ptpnet // TODO: should be: /etc/ptpnet
@@ -0,0 +1,18 @@
#ifndef __PPP_DEV_H
#define __PPP_DEV_H
#include <net_device.h>
#include <net_stack.h>
#include <KPPPInterface.h>
#include <lock.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
struct ppp_device : net_device, DoublyLinkedListLinkImpl<ppp_device> {
KPPPInterface * KPPP_Interface;
uint32 frame_size;
net_fifo ppp_fifo;
};
#endif
@@ -10,6 +10,7 @@ if $(TARGET_PLATFORM) != haiku {
# Unfortunately we get more than we want, namely all POSIX headers. # Unfortunately we get more than we want, namely all POSIX headers.
} }
UsePrivateKernelHeaders ;
UsePrivateHeaders net ; UsePrivateHeaders net ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
headers ] : true ; headers ] : true ;
@@ -19,18 +20,18 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
StaticLibrary libppp.a : StaticLibrary libppp.a :
strlcat.c strlcat.c
driver_settings.c driver_settings.cpp
settings_tools.cpp settings_tools.cpp
KPPPUtils.cpp KPPPUtils.cpp
_libppputils.cpp
PPPInterface.cpp PPPInterface.cpp
PPPInterfaceListener.cpp PPPInterfaceListener.cpp
PPPManager.cpp PPPManager.cpp
MessageDriverSettingsUtils.cpp MessageDriverSettingsUtils.cpp
: libnetwork.so libbnetapi.so
; ;
SEARCH on [ FGristFiles strlcat.c ] = [ FDirName $(HAIKU_TOP) src system libroot posix string ] ; SEARCH on [ FGristFiles strlcat.c ] = [ FDirName $(HAIKU_TOP) src system libroot posix string ] ;
SEARCH on [ FGristFiles driver_settings.c ] = [ FDirName $(HAIKU_TOP) src system libroot os ] ; SEARCH on [ FGristFiles driver_settings.cpp ] = [ FDirName $(HAIKU_TOP) src system libroot os ] ;
SEARCH on [ FGristFiles settings_tools.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ; SEARCH on [ FGristFiles settings_tools.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
SEARCH on [ FGristFiles KPPPUtils.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ; SEARCH on [ FGristFiles KPPPUtils.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
@@ -13,13 +13,20 @@
#include "PPPInterface.h" #include "PPPInterface.h"
#include <cstring> #include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <unistd.h> #include <unistd.h>
#include "_libppputils.h"
#include <Path.h> #include <Path.h>
#include <Directory.h> #include <Directory.h>
#include <Entry.h> #include <Entry.h>
#include <net/if.h>
#include <NetworkDevice.h>
#include <NetworkInterface.h>
/*! \brief Sets the interface to \a ID. /*! \brief Sets the interface to \a ID.
@@ -27,7 +34,9 @@
*/ */
PPPInterface::PPPInterface(ppp_interface_id ID) PPPInterface::PPPInterface(ppp_interface_id ID)
{ {
fFD = open(get_stack_driver_path(), O_RDWR); // printf("direct constructor\n");
int family = AF_INET;
fFD = socket(family, SOCK_DGRAM, 0);
SetTo(ID); SetTo(ID);
} }
@@ -36,7 +45,10 @@ PPPInterface::PPPInterface(ppp_interface_id ID)
//! Copy constructor. //! Copy constructor.
PPPInterface::PPPInterface(const PPPInterface& copy) PPPInterface::PPPInterface(const PPPInterface& copy)
{ {
fFD = open(get_stack_driver_path(), O_RDWR); // printf("Copy constructor\n");
// fFD = open(get_stack_driver_path(), O_RDWR);
int family = AF_INET;
fFD = socket(family, SOCK_DGRAM, 0);
SetTo(copy.ID()); SetTo(copy.ID());
} }
@@ -45,6 +57,7 @@ PPPInterface::PPPInterface(const PPPInterface& copy)
//! Destructor. //! Destructor.
PPPInterface::~PPPInterface() PPPInterface::~PPPInterface()
{ {
// printf("Destructor\n");
if (fFD >= 0) if (fFD >= 0)
close(fFD); close(fFD);
} }
@@ -64,6 +77,7 @@ PPPInterface::InitCheck() const
{ {
if (fFD < 0) if (fFD < 0)
return B_ERROR; return B_ERROR;
if (fID == PPP_UNDEFINED_INTERFACE_ID) if (fID == PPP_UNDEFINED_INTERFACE_ID)
return B_BAD_INDEX; return B_BAD_INDEX;
@@ -87,19 +101,29 @@ PPPInterface::InitCheck() const
status_t status_t
PPPInterface::SetTo(ppp_interface_id ID) PPPInterface::SetTo(ppp_interface_id ID)
{ {
if (fFD < 0) // printf("Set To %ld begin=============================\n", ID);
if (fFD < 0) {
printf("No fFD\n");
return B_ERROR; return B_ERROR;
}
fID = ID;
ppp_interface_info_t info; ppp_interface_info_t info;
// printf("SetTo info:%p\n", &info);
if (GetInterfaceInfo(&info)) { if (GetInterfaceInfo(&info)) {
fName = info.info.name; fName = info.info.name;
fID = ID; fID = ID;
// printf("%s fine: name:%s, fID:%ld\n", __func__, info.info.name, fID);
} else { } else {
fName = ""; fName = "";
fID = PPP_UNDEFINED_INTERFACE_ID; fID = PPP_UNDEFINED_INTERFACE_ID;
// printf("%s fail: name:%s, fID:%ld\n", __func__, "", fID);
return B_ERROR; return B_ERROR;
} }
// printf("Set To %ld end =============================\n", ID);
return B_OK; return B_OK;
} }
@@ -119,23 +143,32 @@ PPPInterface::SetTo(ppp_interface_id ID)
status_t status_t
PPPInterface::Control(uint32 op, void *data, size_t length) const PPPInterface::Control(uint32 op, void *data, size_t length) const
{ {
if (InitCheck() != B_OK) if (InitCheck() != B_OK) {
printf("%s:InitCheck fail\n", __func__);
return InitCheck(); return InitCheck();
}
ppp_control_info control;
ppp_control_info info;
control_net_module_args args; control_net_module_args args;
sprintf(args.ifr_name, "%s", "ppp1");
args.name = PPP_INTERFACE_MODULE_NAME; args.name = PPP_INTERFACE_MODULE_NAME;
args.op = PPPC_CONTROL_INTERFACE; args.op = PPPC_CONTROL_INTERFACE;
args.data = &control; args.data = &info;
args.length = sizeof(control); args.length = sizeof(ppp_control_info);
control.index = ID(); info.index = ID();
control.op = op; info.op = op;
control.data = data; info.data = data;
control.length = length; info.length = length;
return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args); printf("PPPInterface::Control: ppp_control_info %p control_net_module_args %p data %p \n", &info, &args, data);
status_t status = ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args);
if (status != B_OK)
printf("%s:%s: fail\n", __FILE__, __func__);
return status;
} }
@@ -143,6 +176,7 @@ PPPInterface::Control(uint32 op, void *data, size_t length) const
bool bool
PPPInterface::SetUsername(const char *username) const PPPInterface::SetUsername(const char *username) const
{ {
printf("PPPInterface::SetUsername\n");
if (InitCheck() != B_OK || !username) if (InitCheck() != B_OK || !username)
return false; return false;
@@ -155,6 +189,7 @@ PPPInterface::SetUsername(const char *username) const
bool bool
PPPInterface::SetPassword(const char *password) const PPPInterface::SetPassword(const char *password) const
{ {
printf("PPPInterface::SetPassword\n");
if (InitCheck() != B_OK || !password) if (InitCheck() != B_OK || !password)
return false; return false;
@@ -167,6 +202,7 @@ PPPInterface::SetPassword(const char *password) const
bool bool
PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
{ {
printf("PPPInterface::SetAskBeforeConnecting\n");
if (InitCheck() != B_OK) if (InitCheck() != B_OK)
return false; return false;
@@ -188,6 +224,7 @@ PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
status_t status_t
PPPInterface::GetSettingsEntry(BEntry *entry) const PPPInterface::GetSettingsEntry(BEntry *entry) const
{ {
printf("PPPInterface::GetSettingsEntry\n");
if (InitCheck() != B_OK) if (InitCheck() != B_OK)
return InitCheck(); return InitCheck();
else if (!entry || strlen(Name()) == 0) else if (!entry || strlen(Name()) == 0)
@@ -205,10 +242,103 @@ PPPInterface::GetSettingsEntry(BEntry *entry) const
bool bool
PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
{ {
// printf("%s info at:%p", __func__, info);
if (InitCheck() != B_OK || !info) {
// printf("InitCheck fail %s info at:%p", __func__, info);
return false;
}
return Control(PPPC_GET_INTERFACE_INFO, info, sizeof(ppp_interface_info_t))
== B_OK;
}
bool
PPPInterface::ControlDevice(ppp_device_info_t *info) const
{
// printf("%s info at:%p", __func__, info);
if (InitCheck() != B_OK || !info) if (InitCheck() != B_OK || !info)
return false; return false;
return Control(PPPC_GET_INTERFACE_INFO, &info, sizeof(ppp_interface_info_t)) ppp_control_info controlInfo;
controlInfo.op = PPPC_GET_DEVICE_INFO;
controlInfo.index = 0;
controlInfo.data = info;
controlInfo.length = sizeof(ppp_device_info_t);
return Control(PPPC_CONTROL_DEVICE, &controlInfo, sizeof(ppp_control_info))
== B_OK;
}
bool
PPPInterface::ControlOptionHandler(ppp_simple_handler_info_t *info, uint32 handlerindex, uint32 handlerOP) const
{
// printf("%s info at:%p", __func__, info);
if (InitCheck() != B_OK || !info)
return false;
ppp_control_info controlInfo;
controlInfo.index = handlerindex;
controlInfo.op = handlerOP;
controlInfo.data = info;
controlInfo.length = sizeof(ppp_simple_handler_info_t);
return Control(PPPC_CONTROL_OPTION_HANDLER, &controlInfo, sizeof(ppp_control_info))
== B_OK;
}
bool
PPPInterface::ControlChild(void *info, uint32 childindex, uint32 childOP) const
{
// printf("%s info at:%p", __func__, info);
if (InitCheck() != B_OK || !info)
return false;
ppp_control_info controlInfo;
controlInfo.index = childindex;
controlInfo.op = childOP;
controlInfo.data = info;
// controlInfo.length = sizeof(ppp_simple_handler_info_t);
return Control(PPPC_CONTROL_CHILD, &controlInfo, sizeof(ppp_control_info))
== B_OK;
}
bool
PPPInterface::ControlLCPExtension(ppp_simple_handler_info_t *info, uint32 LCPExtensionindex, uint32 LCPExtensionOP) const
{
// printf("%s info at:%p", __func__, info);
if (InitCheck() != B_OK || !info)
return false;
ppp_control_info controlInfo;
controlInfo.index = LCPExtensionindex;
controlInfo.op = LCPExtensionOP;
controlInfo.data = info;
controlInfo.length = sizeof(ppp_simple_handler_info_t);
return Control(PPPC_CONTROL_LCP_EXTENSION, &controlInfo, sizeof(ppp_control_info))
== B_OK;
}
bool
PPPInterface::ControlProtocol(ppp_protocol_info_t *info, uint32 protocolindex, uint32 protocolOP) const
{
// printf("%s info at:%p", __func__, info);
if (InitCheck() != B_OK || !info)
return false;
ppp_control_info controlInfo;
controlInfo.index = protocolindex;
controlInfo.op = protocolOP;
controlInfo.data = info;
controlInfo.length = sizeof(ppp_protocol_info_t);
return Control(PPPC_CONTROL_PROTOCOL, &controlInfo, sizeof(ppp_control_info))
== B_OK; == B_OK;
} }
@@ -222,6 +352,7 @@ PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
bool bool
PPPInterface::GetStatistics(ppp_statistics *statistics) const PPPInterface::GetStatistics(ppp_statistics *statistics) const
{ {
printf("PPPInterface::GetStatistics\n");
if (!statistics) if (!statistics)
return false; return false;
@@ -233,6 +364,7 @@ PPPInterface::GetStatistics(ppp_statistics *statistics) const
bool bool
PPPInterface::HasSettings(const driver_settings *settings) const PPPInterface::HasSettings(const driver_settings *settings) const
{ {
printf("PPPInterface::HasSettings\n");
if (InitCheck() != B_OK || !settings) if (InitCheck() != B_OK || !settings)
return false; return false;
@@ -250,9 +382,24 @@ PPPInterface::Up() const
{ {
if (InitCheck() != B_OK) if (InitCheck() != B_OK)
return false; return false;
BNetworkInterface interface(Name());
if (!interface.Exists())
return false;
int32 currentFlags = interface.Flags();
currentFlags |= IFF_UP;
status_t status = interface.SetFlags(currentFlags);
if (status != B_OK)
return false;
return true;
int32 id = ID(); int32 id = ID();
control_net_module_args args; control_net_module_args args;
sprintf(args.ifr_name, "%s", "ppp1");
args.name = PPP_INTERFACE_MODULE_NAME; args.name = PPP_INTERFACE_MODULE_NAME;
args.op = PPPC_BRING_INTERFACE_UP; args.op = PPPC_BRING_INTERFACE_UP;
args.data = &id; args.data = &id;
@@ -268,9 +415,24 @@ PPPInterface::Down() const
{ {
if (InitCheck() != B_OK) if (InitCheck() != B_OK)
return false; return false;
BNetworkInterface interface(Name());
if (!interface.Exists())
return false;
int32 currentFlags = interface.Flags();
currentFlags &= ~IFF_UP;
status_t status = interface.SetFlags(currentFlags);
if (status != B_OK)
return false;
return true;
int32 id = ID(); int32 id = ID();
control_net_module_args args; control_net_module_args args;
sprintf(args.ifr_name, "%s", "ppp1");
args.name = PPP_INTERFACE_MODULE_NAME; args.name = PPP_INTERFACE_MODULE_NAME;
args.op = PPPC_BRING_INTERFACE_DOWN; args.op = PPPC_BRING_INTERFACE_DOWN;
args.data = &id; args.data = &id;
@@ -292,6 +454,7 @@ bool
PPPInterface::EnableReports(ppp_report_type type, thread_id thread, PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
int32 flags) const int32 flags) const
{ {
printf("PPPInterface::EnableReports\n");
ppp_report_request request; ppp_report_request request;
request.type = type; request.type = type;
request.thread = thread; request.thread = thread;
@@ -311,6 +474,7 @@ PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
bool bool
PPPInterface::DisableReports(ppp_report_type type, thread_id thread) const PPPInterface::DisableReports(ppp_report_type type, thread_id thread) const
{ {
printf("PPPInterface::DisableReports\n");
ppp_report_request request; ppp_report_request request;
request.type = type; request.type = type;
request.thread = thread; request.thread = thread;
@@ -20,16 +20,49 @@
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
#include <cstdio>
#include <cctype> #include <cctype>
#include <settings_tools.h> #include <settings_tools.h>
#include <unistd.h> #include <unistd.h>
#include "_libppputils.h"
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_types.h>
#include <Message.h>
#include <Messenger.h>
#include <NetworkDevice.h>
#include <NetworkInterface.h>
#include <NetworkRoster.h>
#include <NetServer.h>
//! Constructor. Does nothing special. //! Constructor. Does nothing special.
PPPManager::PPPManager() PPPManager::PPPManager()
{ {
fFD = open(get_stack_driver_path(), O_RDWR); // fFD = open(get_stack_driver_path(), O_RDWR);
int family = AF_INET;
fFD = socket(family, SOCK_DGRAM, 0);
// FileDescriptorCloser closer(socket);
// ifaliasreq request;
// strlcpy(request.ifra_name, name, IF_NAMESIZE);
// request.ifra_index = address.Index();
// request.ifra_flags = address.Flags();
// memcpy(&request.ifra_addr, &address.Address().SockAddr(),
// address.Address().Length());
// memcpy(&request.ifra_mask, &address.Mask().SockAddr(),
// address.Mask().Length());
// memcpy(&request.ifra_broadaddr, &address.Broadcast().SockAddr(),
// address.Broadcast().Length());
// if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0)
// return errno;
} }
@@ -133,6 +166,7 @@ PPPManager::Control(uint32 op, void *data, size_t length) const
return B_ERROR; return B_ERROR;
control_net_module_args args; control_net_module_args args;
sprintf(args.ifr_name, "%s", "ppp1");
args.name = PPP_INTERFACE_MODULE_NAME; args.name = PPP_INTERFACE_MODULE_NAME;
args.op = op; args.op = op;
args.data = data; args.data = data;
@@ -169,6 +203,7 @@ PPPManager::ControlModule(const char *name, uint32 op, void *data,
return B_ERROR; return B_ERROR;
control_net_module_args args; control_net_module_args args;
sprintf(args.ifr_name, "%s", "ppp1");
args.name = name; args.name = name;
args.op = op; args.op = op;
args.data = data; args.data = data;
@@ -207,13 +242,72 @@ PPPManager::CreateInterface(const driver_settings *settings) const
ppp_interface_id ppp_interface_id
PPPManager::CreateInterfaceWithName(const char *name) const PPPManager::CreateInterfaceWithName(const char *name) const
{ {
ppp_interface_description_info info; ppp_interface_id ID = InterfaceWithName(name);
info.u.name = name;
if (ID != PPP_UNDEFINED_INTERFACE_ID)
return ID;
BNetworkInterface interface(name);
if (!interface.Exists()) {
// the interface does not exist yet, we have to add it first
BNetworkRoster& roster = BNetworkRoster::Default();
status_t status = roster.AddInterface(interface);
if (status != B_OK) {
fprintf(stderr, "PPPManager::CreateInterfaceWithName: Could not add interface: %s\n",
strerror(status));
return PPP_UNDEFINED_INTERFACE_ID;
}
return InterfaceWithName(name);
}
return PPP_UNDEFINED_INTERFACE_ID;
// ppp_interface_description_info info;
// info.u.name = name;
//
// if (Control(PPPC_CREATE_INTERFACE_WITH_NAME, &info, sizeof(info)) != B_OK)
// return PPP_UNDEFINED_INTERFACE_ID;
// else
// return info.interface;
}
/*! It will remove the complete interface with all
of its addresses.
*/
bool
delete_interface(const char* name)
{
BNetworkInterface interface(name);
// Delete interface
BNetworkRoster& roster = BNetworkRoster::Default();
status_t status = roster.RemoveInterface(interface);
if (status != B_OK) {
fprintf(stderr, "delete_interface: Could not delete interface %s\n",
name);
return false;
}
return true;
}
//! Deletes the interface with the given \a name.
bool
PPPManager::DeleteInterface(const char* name) const
{
ppp_interface_id ID = InterfaceWithName(name);
if (ID == PPP_UNDEFINED_INTERFACE_ID)
return false;
return delete_interface(name);
if (Control(PPPC_CREATE_INTERFACE_WITH_NAME, &info, sizeof(info)) != B_OK)
return PPP_UNDEFINED_INTERFACE_ID;
else
return info.interface;
} }
@@ -253,18 +347,22 @@ PPPManager::Interfaces(int32 *count,
// loop until we get all interfaces // loop until we get all interfaces
while (true) { while (true) {
requestCount = *count = CountInterfaces(filter); requestCount = *count = CountInterfaces(filter);
if (*count == -1) if (*count <= 0) {
printf("No interface, count, first round:%ld\n", *count);
return NULL; return NULL;
}
requestCount += 10; requestCount += 10;
// request some more interfaces in case some are added in the mean time // request some more interfaces in case some are added in the mean time
interfaces = new ppp_interface_id[requestCount]; interfaces = new ppp_interface_id[requestCount];
// printf("interfaces addr: %p\n, requestCount: %ld", interfaces, requestCount);
*count = GetInterfaces(interfaces, requestCount, filter); *count = GetInterfaces(interfaces, requestCount, filter);
if (*count == -1) { if (*count <= 0) {
printf("No interface, count second round:%ld\n", *count);
delete interfaces; delete interfaces;
return NULL; return NULL;
} }
if (*count < requestCount) if (*count < requestCount)
break; break;
@@ -345,12 +443,17 @@ PPPManager::InterfaceWithName(const char *name) const
int32 count; int32 count;
ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES); ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
if (!interfaces) if (!interfaces || count <= 0) {
printf("ERROR: Could not get ppp name:%s\n", name);
return PPP_UNDEFINED_INTERFACE_ID; return PPP_UNDEFINED_INTERFACE_ID;
}
// printf("first ID:%ld count:%ld\n", interfaces[0], count);
ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID; ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
PPPInterface interface; PPPInterface interface;
ppp_interface_info_t info; ppp_interface_info_t info;
// printf("internal info is at: %p\n", &info);
for (int32 index = 0; index < count; index++) { for (int32 index = 0; index < count; index++) {
interface.SetTo(interfaces[index]); interface.SetTo(interfaces[index]);
@@ -374,11 +477,79 @@ PPPManager::InterfaceWithName(const char *name) const
} }
//! Returns the number of existing interfaces or a negative value on error.
bool
is_ppp_interface(const char* name)
{
// size_t length = strlen(name);
// if (length < 8)
// putchar('\t');
// else
// printf("\n\t");
// get link level interface for this interface
BNetworkInterface interface(name);
BNetworkAddress linkAddress;
status_t status = interface.GetHardwareAddress(linkAddress);
if (status == B_OK) {
// const char *type = "unknown";
switch (linkAddress.LinkLevelType()) {
case IFT_ETHER:
// type = "Ethernet";
// printf("%s\n", type);
break;
case IFT_LOOP:
// type = "Local Loopback";
// printf("%s\n", type);
break;
case IFT_MODEM:
// type = "Modem";
// printf("%s\n", type);
break;
case IFT_PPP:
// type = "PPP";
// printf("%s\n", type);
return true;
break;
default:
// printf("%s\n", type);
;
}
}
return false;
}
//! Returns the number of ppp interfaces
int32
count_ppp_interface(void)
{
int32 count = 0;
// get a list of all ppp interfaces
BNetworkRoster& roster = BNetworkRoster::Default();
BNetworkInterface interface;
uint32 cookie = 0;
while (roster.GetNextInterface(&cookie, interface) == B_OK) {
if (is_ppp_interface(interface.Name()))
count++;
}
return count;
}
//! Returns the number of existing interfaces or a negative value on error. //! Returns the number of existing interfaces or a negative value on error.
int32 int32
PPPManager::CountInterfaces(ppp_interface_filter filter) const PPPManager::CountInterfaces(ppp_interface_filter filter) const
{ {
return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter)); // return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter));
return count_ppp_interface();
} }
@@ -1,24 +0,0 @@
/*
* Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
* Distributed under the terms of the MIT License.
*/
#include <OS.h>
#include "_libppputils.h"
#include <cstdlib>
#include <cstring>
char*
get_stack_driver_path()
{
char *path;
// user-defined stack driver path?
path = getenv("NET_STACK_DRIVER_PATH");
if (path)
return path;
// use the default stack driver path
return NET_STACK_DRIVER_PATH;
}
@@ -1,15 +0,0 @@
/*
* Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
* Distributed under the terms of the MIT License.
*/
#ifndef __libppputils__h
#define __libppputils__h
#include <net_stack_driver.h>
char *get_stack_driver_path();
#endif
@@ -39,6 +39,12 @@ class PPPInterface {
bool GetInterfaceInfo(ppp_interface_info_t *info) const; bool GetInterfaceInfo(ppp_interface_info_t *info) const;
bool GetStatistics(ppp_statistics *statistics) const; bool GetStatistics(ppp_statistics *statistics) const;
bool HasSettings(const driver_settings *settings) const; bool HasSettings(const driver_settings *settings) const;
bool ControlDevice(ppp_device_info_t *info) const;
bool ControlProtocol(ppp_protocol_info_t *info, uint32 protocolindex, uint32 procotolOP) const;
bool ControlOptionHandler(ppp_simple_handler_info_t *info, uint32 handlerindex, uint32 handlerOP) const;
bool ControlLCPExtension(ppp_simple_handler_info_t *info, uint32 LCPExtensionindex, uint32 LCPExtensionOP) const;
bool ControlChild(void *info, uint32 childindex, uint32 childOP) const;
bool Up() const; bool Up() const;
bool Down() const; bool Down() const;
@@ -6,6 +6,7 @@
#ifndef _PPP_MANAGER__H #ifndef _PPP_MANAGER__H
#define _PPP_MANAGER__H #define _PPP_MANAGER__H
#include <Directory.h>
#include <KPPPManager.h> #include <KPPPManager.h>
#include <String.h> #include <String.h>
@@ -33,6 +34,7 @@ class PPPManager {
ppp_interface_id CreateInterface(const driver_settings *settings) const; ppp_interface_id CreateInterface(const driver_settings *settings) const;
ppp_interface_id CreateInterfaceWithName(const char *name) const; ppp_interface_id CreateInterfaceWithName(const char *name) const;
bool DeleteInterface(ppp_interface_id ID) const; bool DeleteInterface(ppp_interface_id ID) const;
bool DeleteInterface(const char* name) const;
ppp_interface_id *Interfaces(int32 *count, ppp_interface_id *Interfaces(int32 *count,
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const; ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const;
@@ -833,6 +833,9 @@ init_stack()
// TODO: for now! // TODO: for now!
register_domain_datalink_protocols(AF_INET, IFT_LOOP, register_domain_datalink_protocols(AF_INET, IFT_LOOP,
"network/datalink_protocols/loopback_frame/v1", NULL); "network/datalink_protocols/loopback_frame/v1", NULL);
// add ppp datalink protocol
register_domain_datalink_protocols(AF_INET, IFT_PPP,
"network/datalink_protocols/ppp_frame/v1", NULL);
register_domain_datalink_protocols(AF_INET6, IFT_LOOP, register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
"network/datalink_protocols/loopback_frame/v1", NULL); "network/datalink_protocols/loopback_frame/v1", NULL);
register_domain_datalink_protocols(AF_INET, IFT_ETHER, register_domain_datalink_protocols(AF_INET, IFT_ETHER,
+2 -2
View File
@@ -10,8 +10,8 @@ SubInclude HAIKU_TOP src bin network ftpd ;
SubInclude HAIKU_TOP src bin network ifconfig ; SubInclude HAIKU_TOP src bin network ifconfig ;
SubInclude HAIKU_TOP src bin network mount_nfs ; SubInclude HAIKU_TOP src bin network mount_nfs ;
SubInclude HAIKU_TOP src bin network netstat ; SubInclude HAIKU_TOP src bin network netstat ;
#SubInclude HAIKU_TOP src bin network pppconfig ; SubInclude HAIKU_TOP src bin network pppconfig ;
#SubInclude HAIKU_TOP src bin network ppp_up ; SubInclude HAIKU_TOP src bin network ppp_up ;
SubInclude HAIKU_TOP src bin network ping ; SubInclude HAIKU_TOP src bin network ping ;
SubInclude HAIKU_TOP src bin network ping6 ; SubInclude HAIKU_TOP src bin network ping6 ;
SubInclude HAIKU_TOP src bin network route ; SubInclude HAIKU_TOP src bin network route ;
+6 -3
View File
@@ -1,4 +1,4 @@
SubDir HAIKU_TOP src bin ppp_up ; SubDir HAIKU_TOP src bin network ppp_up ;
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ; SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
@@ -8,7 +8,10 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
# Unfortunately we get more than we want, namely all POSIX headers. # Unfortunately we get more than we want, namely all POSIX headers.
} }
UsePrivateHeaders net ; UsePrivateKernelHeaders ;
UsePrivateHeaders net app libroot shared interface libbe be root tracker textencoding
root ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
headers ] : true ; headers ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
@@ -24,7 +27,7 @@ BinCommand ppp_up :
PPPStatusWindow.cpp PPPStatusWindow.cpp
PPPUpApplication.cpp PPPUpApplication.cpp
: :
libppp.a be libppp.a be $(TARGET_LIBSUPC++) translation $(HAIKU_LOCALE_LIBS) root $(TARGET_NETWORK_LIBS)
; ;
# Installation # Installation
+2 -1
View File
@@ -6,8 +6,9 @@
#ifndef STATUS_VIEW__H #ifndef STATUS_VIEW__H
#define STATUS_VIEW__H #define STATUS_VIEW__H
#include <View.h> #include <Button.h>
#include <PPPInterface.h> #include <PPPInterface.h>
#include <StringView.h>
class PPPStatusView : public BView { class PPPStatusView : public BView {
+3 -2
View File
@@ -1,4 +1,4 @@
SubDir HAIKU_TOP src bin pppconfig ; SubDir HAIKU_TOP src bin network pppconfig ;
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ; SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
@@ -8,6 +8,7 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
# Unfortunately we get more than we want, namely all POSIX headers. # Unfortunately we get more than we want, namely all POSIX headers.
} }
UsePrivateKernelHeaders ;
UsePrivateHeaders net ; UsePrivateHeaders net ;
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
headers ] : true ; headers ] : true ;
@@ -17,7 +18,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
BinCommand pppconfig : BinCommand pppconfig :
pppconfig.cpp pppconfig.cpp
: :
be libppp.a be libppp.a $(TARGET_LIBSUPC++) $(TARGET_NETWORK_LIBS)
; ;
# Installation -- in the test directory for the time being # Installation -- in the test directory for the time being
+488 -41
View File
@@ -40,33 +40,35 @@ status_t
show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
{ {
PPPManager manager; PPPManager manager;
if(manager.InitCheck() != B_OK) { if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n"); fprintf(stderr, "Error: Could not load interface manager!\n");
return -1; return -1;
} }
int32 count; int32 count = 0;
ppp_interface_id *interfaces = manager.Interfaces(&count, filter); ppp_interface_id *interfaces = manager.Interfaces(&count, filter);
if(!interfaces) { if (!interfaces || count <= 0) {
fprintf(stderr, "Error: Could not get interfaces information!\n"); fprintf(stderr, "Error: Could not get interfaces information!\n");
return -1; return -1;
} }
fprintf(stderr, "Get %ld ppp interfaces, first is %ld!\n", count, interfaces[0]);
ppp_interface_info_t info; ppp_interface_info_t info;
PPPInterface interface; PPPInterface interface;
printf("Listing PPP interfaces:\n"); printf("Listing PPP interfaces:\n");
// print out information for each interface // print out information for each interface
for(int32 index = 0; index < count; index++) { for (int32 index = 0; index < count; index++) {
interface.SetTo(interfaces[index]); interface.SetTo(interfaces[index]);
if(interface.InitCheck() == B_OK) { if (interface.InitCheck() == B_OK) {
interface.GetInterfaceInfo(&info); interface.GetInterfaceInfo(&info);
printf("\n"); printf("\n");
// type and unit (if it has one) // type and unit (if it has one)
if(info.info.if_unit >= 0) { if (info.info.if_unit >= 0) {
printf("Type: Visible\n"); printf("Type: Visible\n");
printf("\tInterface: ppp%ld\n", info.info.if_unit); printf("\tInterface: ppp%ld\n", info.info.if_unit);
} else } else
@@ -79,9 +81,9 @@ show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
// mode // mode
printf("\tMode: "); printf("\tMode: ");
if(info.info.mode == PPP_CLIENT_MODE) if (info.info.mode == PPP_CLIENT_MODE)
printf("Client\n"); printf("Client\n");
else if(info.info.mode == PPP_SERVER_MODE) else if (info.info.mode == PPP_SERVER_MODE)
printf("Server\n"); printf("Server\n");
else else
printf("Unknown\n"); printf("Unknown\n");
@@ -118,13 +120,13 @@ status_t
create(const char *name, bool bringUp = true) create(const char *name, bool bringUp = true)
{ {
PPPManager manager; PPPManager manager;
if(manager.InitCheck() != B_OK) { if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n"); fprintf(stderr, "Error: Could not load interface manager!\n");
return -1; return -1;
} }
PPPInterface interface(manager.CreateInterfaceWithName(name)); PPPInterface interface(manager.CreateInterfaceWithName(name));
if(interface.InitCheck() != B_OK) { if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not create interface: %s!\n", name); fprintf(stderr, "Error: Could not create interface: %s!\n", name);
return -1; return -1;
} }
@@ -134,13 +136,13 @@ create(const char *name, bool bringUp = true)
ppp_interface_info_t info; ppp_interface_info_t info;
interface.GetInterfaceInfo(&info); interface.GetInterfaceInfo(&info);
if(info.info.if_unit >= 0) if (info.info.if_unit >= 0)
printf("Interface: ppp%ld\n", info.info.if_unit); printf("Interface: ppp%ld\n", info.info.if_unit);
else else
printf("This interface is hidden! You can delete it by typing:\n" printf("This interface is hidden! You can delete it by typing:\n"
"pppconfig delete %ld\n", interface.ID()); "pppconfig delete %ld\n", interface.ID());
if(bringUp) { if (bringUp) {
interface.Up(); interface.Up();
printf("Connecting in background...\n"); printf("Connecting in background...\n");
} }
@@ -153,22 +155,22 @@ static
status_t status_t
connect(const char *name) connect(const char *name)
{ {
if(!name || strlen(name) == 0) if (!name || strlen(name) == 0)
return -1; return -1;
PPPManager manager; PPPManager manager;
if(manager.InitCheck() != B_OK) { if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n"); fprintf(stderr, "Error: Could not load interface manager!\n");
return -1; return -1;
} }
PPPInterface interface(manager.InterfaceWithName(name)); PPPInterface interface(manager.InterfaceWithName(name));
if(interface.InitCheck() != B_OK) { if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name); fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1; return -1;
} }
if(!interface.Up()) { if (!interface.Up()) {
fprintf(stderr, "Error: Could not connect!\n"); fprintf(stderr, "Error: Could not connect!\n");
return -1; return -1;
} }
@@ -181,24 +183,435 @@ connect(const char *name)
static static
status_t status_t
disconnect(const char *name) setuser(const char *name, const char* user)
{ {
if(!name || strlen(name) == 0) if (!name || strlen(name) == 0)
return -1; return -1;
if (!user || strlen(user) == 0)
return -1;
PPPManager manager; PPPManager manager;
if(manager.InitCheck() != B_OK) { if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n"); fprintf(stderr, "Error: Could not load interface manager!\n");
return -1; return -1;
} }
PPPInterface interface(manager.InterfaceWithName(name)); PPPInterface interface(manager.InterfaceWithName(name));
if(interface.InitCheck() != B_OK) { if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name); fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1; return -1;
} }
if(!interface.Down()) { if (!interface.SetUsername(user)) {
fprintf(stderr, "Error: Could not SetUsername %s!\n", user);
return -1;
}
return 0;
}
static
status_t
setpass(const char *name, const char* pass)
{
if (!name || strlen(name) == 0)
return -1;
if (!pass || strlen(pass) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
if (!interface.SetPassword(pass)) {
fprintf(stderr, "Error: Could not SetUsername %s!\n", pass);
return -1;
}
return 0;
}
static
status_t
setaskbeforeconnect(const char *name, const char* connect)
{
if (!name || strlen(name) == 0)
return -1;
bool askBeforeConnecting = false;
if (connect || !strcmp(connect, "true") || !strcmp(connect, "ask") ||
!strcmp(connect, "yes") || !strcmp(connect, "y"))
askBeforeConnecting = true;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
if (!interface.SetAskBeforeConnecting(askBeforeConnecting)) {
fprintf(stderr, "Error: Could not connect %s!\n", connect);
return -1;
}
return 0;
}
static
status_t
getstatistics(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
ppp_statistics pppStatistics;
if (interface.GetStatistics(&pppStatistics) != B_OK) {
fprintf(stderr, "Error: Could not getstatistics: %s!\n", name);
return -1;
}
return 0;
}
static
status_t
hassettings(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
driver_settings settings;
if (interface.HasSettings(&settings) != B_OK) {
fprintf(stderr, "Error: Could not getstatistics: %s!\n", name);
return -1;
}
return 0;
}
static
status_t
enablereports(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
ppp_report_type type = PPP_ALL_REPORTS;
thread_id thread = 0;
int32 flags = 0;
if (interface.EnableReports(type, thread, flags) != true) {
fprintf(stderr, "Error: Could not EnableReports: %s!\n", name);
return -1;
}
return 0;
}
static
status_t
disablereports(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
ppp_report_type type = PPP_ALL_REPORTS;
thread_id thread = 0;
if (interface.DisableReports(type, thread) != true) {
fprintf(stderr, "Error: Could not EnableReports: %s!\n", name);
return -1;
}
return 0;
}
static
status_t
controlchild(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
ppp_simple_handler_info_t info;
if (interface.ControlChild(&info, 0, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
return -1;
}
printf("LCPExtensionHandler: %s\n", info.info.name);
printf("isEnabled: %d\n", info.info.isEnabled);
if (interface.ControlChild(&info, 0, PPPC_ENABLE) != true) {
fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
return -1;
}
return 0;
}
static
status_t
controllcpextension(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
ppp_simple_handler_info_t info;
if (interface.ControlLCPExtension(&info, 1, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
return -1;
}
printf("LCPExtensionHandler: %s\n", info.info.name);
printf("isEnabled: %d\n", info.info.isEnabled);
if (interface.ControlLCPExtension(&info, 1, PPPC_ENABLE) != true) {
fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
return -1;
}
return 0;
}
static
status_t
controloptionhandler(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
ppp_simple_handler_info_t info;
if (interface.ControlOptionHandler(&info, 0, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
return -1;
}
printf("protocol: %s\n", info.info.name);
printf("isEnabled: %d\n", info.info.isEnabled);
if (interface.ControlOptionHandler(&info, 0, PPPC_ENABLE) != true) {
fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
return -1;
}
return 0;
}
static
status_t
controlprotocol(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
ppp_protocol_info_t info;
if (interface.ControlProtocol(&info, 0, PPPC_GET_PROTOCOL_INFO) != true) {
fprintf(stderr, "Error: Could not PPPC_GET_PROTOCOL_INFO: %s!\n", name);
return -1;
}
printf("protocol: %s\n", info.info.name);
printf("type: %s\n", info.info.type);
printf("activationPhase: %d\n", info.info.activationPhase);
printf("addressFamily: %ld\n", info.info.addressFamily);
printf("flags: %ld\n", info.info.flags);
printf("side: %d\n", info.info.side);
printf("level: %d\n", info.info.level);
printf("connectionPhase: %d\n", info.info.connectionPhase);
printf("protocolNumber: %d\n", info.info.protocolNumber);
printf("isEnabled: %d\n", info.info.isEnabled);
printf("isUpRequested: %d\n", info.info.isUpRequested);
if (interface.ControlProtocol(&info, 0, PPPC_ENABLE) != true) {
fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
return -1;
}
return 0;
}
static
status_t
controldevice(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
ppp_device_info_t info;
if (interface.ControlDevice(&info) != true) {
fprintf(stderr, "Error: Could not ControlDevice: %s!\n", name);
return -1;
}
printf("name: %s\n", info.info.name);
printf("MTU: %ld\n", info.info.MTU);
printf("inputTransferRate: %ld\n", info.info.inputTransferRate);
printf("outputTransferRate: %ld\n", info.info.outputTransferRate);
printf("outputBytesCount: %ld\n", info.info.outputBytesCount);
printf("isUp: %d\n", info.info.isUp);
return 0;
}
static
status_t
disconnect(const char *name)
{
if (!name || strlen(name) == 0)
return -1;
PPPManager manager;
if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n");
return -1;
}
PPPInterface interface(manager.InterfaceWithName(name));
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1;
}
if (!interface.Down()) {
fprintf(stderr, "Error: Could not disconnect!\n"); fprintf(stderr, "Error: Could not disconnect!\n");
return -1; return -1;
} }
@@ -211,16 +624,16 @@ static
status_t status_t
delete_interface(const char *name) delete_interface(const char *name)
{ {
if(!name || strlen(name) == 0) if (!name || strlen(name) == 0)
return -1; return -1;
PPPManager manager; PPPManager manager;
if(manager.InitCheck() != B_OK) { if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n"); fprintf(stderr, "Error: Could not load interface manager!\n");
return -1; return -1;
} }
if(!manager.DeleteInterface(manager.InterfaceWithName(name))) { if (!manager.DeleteInterface(name)) {
fprintf(stderr, "Error: Could not delete interface!\n"); fprintf(stderr, "Error: Could not delete interface!\n");
return -1; return -1;
} }
@@ -233,26 +646,33 @@ static
status_t status_t
show_details(const char *name) show_details(const char *name)
{ {
if(!name || strlen(name) == 0) if (!name || strlen(name) == 0)
return -1; return -1;
PPPManager manager; PPPManager manager;
if(manager.InitCheck() != B_OK) { if (manager.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not load interface manager!\n"); fprintf(stderr, "Error: Could not load interface manager!\n");
return -1; return -1;
} }
PPPInterface interface(manager.InterfaceWithName(name)); ppp_interface_id ID = manager.InterfaceWithName(name);
if(interface.InitCheck() != B_OK) { if (ID <= 0) {
fprintf(stderr, "Error: Could not find interface: %s!\n", name); fprintf(stderr, "Error: Could not find interface: %s!\n", name);
return -1; return -1;
} }
PPPInterface interface(ID);
if (interface.InitCheck() != B_OK) {
fprintf(stderr, "Error: Could not find interface ID: %ld!\n", ID);
return -1;
}
ppp_interface_info_t info; ppp_interface_info_t info;
// printf("ppp_interface_info_t addr:%p\n", &info);
interface.GetInterfaceInfo(&info); interface.GetInterfaceInfo(&info);
// type and name (if it has one) // type and name (if it has one)
if(info.info.if_unit >= 0) { if (info.info.if_unit >= 0) {
printf("Type: Visible\n"); printf("Type: Visible\n");
printf("Interface: ppp%ld\n", info.info.if_unit); printf("Interface: ppp%ld\n", info.info.if_unit);
} else } else
@@ -277,9 +697,9 @@ show_details(const char *name)
// mode // mode
printf("Mode: "); printf("Mode: ");
if(info.info.mode == PPP_CLIENT_MODE) if (info.info.mode == PPP_CLIENT_MODE)
printf("Client\n"); printf("Client\n");
else if(info.info.mode == PPP_SERVER_MODE) else if (info.info.mode == PPP_SERVER_MODE)
printf("Server\n"); printf("Server\n");
else else
printf("Unknown\n"); printf("Unknown\n");
@@ -310,24 +730,51 @@ show_details(const char *name)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
if(argc == 2) { if (argc == 2) {
if(!strcmp(argv[1], "show") || !strcmp(argv[1], "-a")) if (!strcmp(argv[1], "show") || !strcmp(argv[1], "-a"))
return show(PPP_ALL_INTERFACES); return show(PPP_ALL_INTERFACES);
else else
return print_help(); return print_help();
}if(argc == 3) { }if (argc == 3) {
if(!strcmp(argv[1], "init")) if (!strcmp(argv[1], "init"))
return create(argv[2], false); return create(argv[2], false);
else if(!strcmp(argv[1], "create")) else if (!strcmp(argv[1], "create"))
return create(argv[2], true); return create(argv[2], true);
else if(!strcmp(argv[1], "connect")) else if (!strcmp(argv[1], "connect"))
return connect(argv[2]); return connect(argv[2]);
else if(!strcmp(argv[1], "disconnect")) else if (!strcmp(argv[1], "disconnect"))
return disconnect(argv[2]); return disconnect(argv[2]);
else if(!strcmp(argv[1], "delete")) else if (!strcmp(argv[1], "delete"))
return delete_interface(argv[2]); return delete_interface(argv[2]);
else if(!strcmp(argv[1], "details")) else if (!strcmp(argv[1], "details"))
return show_details(argv[2]); return show_details(argv[2]);
else if (!strcmp(argv[1], "getstatistics"))
return getstatistics(argv[2]);
else if (!strcmp(argv[1], "hassettings"))
return hassettings(argv[2]);
else if (!strcmp(argv[1], "enablereports"))
return enablereports(argv[2]);
else if (!strcmp(argv[1], "disablereports"))
return disablereports(argv[2]);
else if (!strcmp(argv[1], "controldevice"))
return controldevice(argv[2]);
else if (!strcmp(argv[1], "controlprotocol"))
return controlprotocol(argv[2]);
else if (!strcmp(argv[1], "controloptionhandler"))
return controloptionhandler(argv[2]);
else if (!strcmp(argv[1], "controllcpextension"))
return controllcpextension(argv[2]);
else if (!strcmp(argv[1], "controlchild"))
return controlchild(argv[2]);
else
return print_help();
} if (argc == 4) {
if (!strcmp(argv[1], "setuser"))
return setuser(argv[2], argv[3]);
else if (!strcmp(argv[1], "setpass"))
return setpass(argv[2], argv[3]);
else if (!strcmp(argv[1], "setaskbeforeconnect"))
return setaskbeforeconnect(argv[2], argv[3]);
else else
return print_help(); return print_help();
} else } else