PPP: Port to the new stack.
Signed-off-by: Augustin Cavalier <[email protected]> This is a squash of the 42 commits by @mshlyn, as I couldn't find a way to break them into logical chunks. I did not include these in the build, as it appears that they only partially work anyway, and much more cleanup is still needed. However, this is a huge improvement on what was in the tree before, which looked horrendous and didn't even compile (as it was designed for the old stack). Mostly fixes #812.
This commit is contained in:
committed by
Augustin Cavalier
parent
7121057cb7
commit
e3724c38cb
@@ -134,7 +134,7 @@ SYSTEM_NETWORK_DATALINK_PROTOCOLS =
|
|||||||
loopback_frame
|
loopback_frame
|
||||||
;
|
;
|
||||||
|
|
||||||
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe ;
|
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe KPPPManager ;
|
||||||
|
|
||||||
SYSTEM_NETWORK_PROTOCOLS =
|
SYSTEM_NETWORK_PROTOCOLS =
|
||||||
icmp icmp6 ipv4 ipv6
|
icmp icmp6 ipv4 ipv6
|
||||||
|
|||||||
@@ -6,3 +6,4 @@ SubInclude HAIKU_TOP src add-ons kernel network dns_resolver ;
|
|||||||
SubInclude HAIKU_TOP src add-ons kernel network notifications ;
|
SubInclude HAIKU_TOP src add-ons kernel network notifications ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network protocols ;
|
SubInclude HAIKU_TOP src add-ons kernel network protocols ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network stack ;
|
SubInclude HAIKU_TOP src add-ons kernel network stack ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel network ppp ;
|
SubDir HAIKU_TOP src add-ons kernel network ppp ;
|
||||||
|
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
|
# SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp pap ;
|
SubInclude HAIKU_TOP src add-ons kernel network ppp pap ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
SubInclude HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
||||||
SubInclude HAIKU_TOP src add-ons kernel network ppp shared ;
|
SubInclude HAIKU_TOP src add-ons kernel network ppp shared ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
|
||||||
|
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
|
||||||
|
|||||||
@@ -1,41 +1,51 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
SubDir HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
if $(TARGET_PLATFORM) != haiku {
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
|
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||||
|
# Needed for the atomic_add64() prototype.
|
||||||
|
}
|
||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
# We need the public network headers also when not compiling for Haiku.
|
# We need the public network headers also when not compiling for 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 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 ;
|
||||||
|
|||||||
@@ -13,11 +13,29 @@
|
|||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
#include <settings_tools.h>
|
#include <settings_tools.h>
|
||||||
|
|
||||||
|
#include <PPPoEDevice.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <netinet/in_var.h>
|
|
||||||
#include <core_funcs.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
#include <net/route.h>
|
||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
// For updating resolv.conf
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define RESOLV_CONF_FILE "/boot/system/settings/network/resolv.conf"
|
||||||
|
|
||||||
|
extern net_buffer_module_info *gBufferModule;
|
||||||
|
static struct net_datalink_module_info *sDatalinkModule;
|
||||||
|
static struct net_stack_module_info *sStackModule;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -26,7 +44,7 @@ static int sFD;
|
|||||||
// the file descriptor for debug output
|
// the file descriptor for debug output
|
||||||
static char sDigits[] = "0123456789ABCDEF";
|
static char sDigits[] = "0123456789ABCDEF";
|
||||||
void
|
void
|
||||||
dump_packet(struct mbuf *packet, const char *direction)
|
dump_packet(net_buffer *packet, const char *direction)
|
||||||
{
|
{
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return;
|
return;
|
||||||
@@ -87,6 +105,8 @@ IPCP::IPCP(KPPPInterface& interface, driver_parameter *settings)
|
|||||||
ParseSideRequests(get_parameter_with_name(IPCP_PEER_SIDE_KEY, Settings()),
|
ParseSideRequests(get_parameter_with_name(IPCP_PEER_SIDE_KEY, Settings()),
|
||||||
PPP_PEER_SIDE);
|
PPP_PEER_SIDE);
|
||||||
|
|
||||||
|
get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule);
|
||||||
|
get_module(NET_DATALINK_MODULE_NAME, (module_info **)&sDatalinkModule);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
sFD = open("/boot/home/ipcpdebug", O_WRONLY | O_CREAT | O_TRUNC);
|
sFD = open("/boot/home/ipcpdebug", O_WRONLY | O_CREAT | O_TRUNC);
|
||||||
#endif
|
#endif
|
||||||
@@ -95,6 +115,9 @@ IPCP::IPCP(KPPPInterface& interface, driver_parameter *settings)
|
|||||||
|
|
||||||
IPCP::~IPCP()
|
IPCP::~IPCP()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
put_module(NET_DATALINK_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
close(sFD);
|
close(sFD);
|
||||||
#endif
|
#endif
|
||||||
@@ -205,7 +228,7 @@ IPCP::Down()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
IPCP::Send(struct mbuf *packet, uint16 protocolNumber)
|
IPCP::Send(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: Send(0x%X)\n", protocolNumber);
|
TRACE("IPCP: Send(0x%X)\n", protocolNumber);
|
||||||
|
|
||||||
@@ -220,13 +243,13 @@ IPCP::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
|
|
||||||
ERROR("IPCP: Send() failed because of wrong state or protocol number!\n");
|
ERROR("IPCP: Send() failed because of wrong state or protocol number!\n");
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
IPCP::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: Receive(0x%X)\n", protocolNumber);
|
TRACE("IPCP: Receive(0x%X)\n", protocolNumber);
|
||||||
|
|
||||||
@@ -239,21 +262,16 @@ IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
if (protocolNumber != IPCP_PROTOCOL)
|
if (protocolNumber != IPCP_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();
|
||||||
|
|
||||||
// remove padding
|
if (ntohs(data.length) < 4)
|
||||||
int32 length = packet->m_len;
|
|
||||||
if(packet->m_flags & M_PKTHDR)
|
|
||||||
length = packet->m_pkthdr.len;
|
|
||||||
length -= ntohs(data->length);
|
|
||||||
if(length)
|
|
||||||
m_adj(packet, -length);
|
|
||||||
|
|
||||||
if(ntohs(data->length) < 4)
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// packet is freed by event methods
|
// packet is freed by event methods
|
||||||
switch(data->code) {
|
switch (data.code) {
|
||||||
case PPP_CONFIGURE_REQUEST:
|
case PPP_CONFIGURE_REQUEST:
|
||||||
RCREvent(packet);
|
RCREvent(packet);
|
||||||
break;
|
break;
|
||||||
@@ -290,23 +308,26 @@ IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
IPCP::ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber)
|
IPCP::ReceiveIPPacket(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
if (protocolNumber != IP_PROTOCOL || State() != PPP_OPENED_STATE)
|
if (protocolNumber != IP_PROTOCOL || State() != PPP_OPENED_STATE)
|
||||||
return PPP_UNHANDLED;
|
return PPP_UNHANDLED;
|
||||||
|
|
||||||
// TODO: add VJC support (the packet would be decoded here)
|
// TODO: add VJC support (the packet would be decoded here)
|
||||||
|
|
||||||
if (gProto[IPPROTO_IP] && gProto[IPPROTO_IP]->pr_input) {
|
if (packet)
|
||||||
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
dump_packet(packet, "incoming");
|
dump_packet(packet, "incoming");
|
||||||
#endif
|
#endif
|
||||||
Interface().UpdateIdleSince();
|
Interface().UpdateIdleSince();
|
||||||
gProto[IPPROTO_IP]->pr_input(packet, 0);
|
|
||||||
|
TRACE("We got 1 IP packet from %s::%s\n", __FILE__, __func__);
|
||||||
|
gBufferModule->free(packet);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
} else {
|
} else {
|
||||||
ERROR("IPCP: Error: Could not find input function for IP!\n");
|
ERROR("IPCP: Error: Could not find input function for IP!\n");
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -374,6 +395,7 @@ IPCP::ParseSideRequests(const driver_parameter *requests, ppp_side side)
|
|||||||
// all values are IP addresses, so parse the address here
|
// all values are IP addresses, so parse the address here
|
||||||
if (strcasecmp(requests->parameters[index].values[0], "auto")) {
|
if (strcasecmp(requests->parameters[index].values[0], "auto")) {
|
||||||
address = inet_addr(requests->parameters[index].values[0]);
|
address = inet_addr(requests->parameters[index].values[0]);
|
||||||
|
// address = INADDR_ANY;
|
||||||
if (address == INADDR_NONE)
|
if (address == INADDR_NONE)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -398,75 +420,155 @@ IPCP::ParseSideRequests(const driver_parameter *requests, ppp_side side)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
set_interface_address(net_domain* domain, struct ifaliasreq* inreq)
|
||||||
|
{
|
||||||
|
size_t size = sizeof(struct ifaliasreq);
|
||||||
|
return sDatalinkModule->control(domain, B_SOCKET_SET_ALIAS, inreq, &size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::UpdateAddresses()
|
IPCP::UpdateAddresses()
|
||||||
{
|
{
|
||||||
|
TRACE("%s::%s: entering UpdateAddresses\n", __FILE__, __func__);
|
||||||
RemoveRoutes();
|
RemoveRoutes();
|
||||||
|
|
||||||
if (State() != PPP_OPENED_STATE && !Interface().DoesConnectOnDemand())
|
if (State() != PPP_OPENED_STATE && !Interface().DoesConnectOnDemand())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct in_aliasreq inreq;
|
TRACE("%s::%s: entering ChangeAddress\n", __FILE__, __func__);
|
||||||
struct ifreq ifreqAddress, ifreqDestination;
|
if (sDatalinkModule == NULL) {
|
||||||
memset(&inreq, 0, sizeof(struct in_aliasreq));
|
TRACE("%s::%s: some module not found!\n", __FILE__, __func__);
|
||||||
memset(&ifreqAddress, 0, sizeof(struct ifreq));
|
return;
|
||||||
memset(&ifreqDestination, 0, sizeof(struct ifreq));
|
}
|
||||||
memset(&fGateway, 0, sizeof(struct sockaddr_in));
|
|
||||||
|
|
||||||
|
struct sockaddr newAddr = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
struct sockaddr netmask = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
struct sockaddr broadaddr = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||||
|
|
||||||
// create local address
|
|
||||||
inreq.ifra_addr.sin_family = AF_INET;
|
|
||||||
if (fLocalRequests.address != INADDR_ANY)
|
if (fLocalRequests.address != INADDR_ANY)
|
||||||
inreq.ifra_addr.sin_addr.s_addr = fLocalRequests.address;
|
memcpy(newAddr.sa_data + 2, &fLocalRequests.address, sizeof(in_addr_t));
|
||||||
else if(fLocalConfiguration.address == INADDR_ANY)
|
else if (fLocalConfiguration.address == INADDR_ANY) {
|
||||||
inreq.ifra_addr.sin_addr.s_addr = 0x010F0F0F; // was: INADDR_BROADCAST
|
in_addr_t inaddrBroadcast = 0x010F0F0F; // was: INADDR_BROADCAST
|
||||||
else
|
memcpy(newAddr.sa_data + 2, &inaddrBroadcast, sizeof(in_addr_t));
|
||||||
inreq.ifra_addr.sin_addr.s_addr = fLocalConfiguration.address;
|
} else
|
||||||
inreq.ifra_addr.sin_len = sizeof(struct sockaddr_in);
|
memcpy(newAddr.sa_data + 2, &fLocalConfiguration.address, sizeof(in_addr_t));
|
||||||
memcpy(&ifreqAddress.ifr_addr, &inreq.ifra_addr, sizeof(struct sockaddr_in));
|
|
||||||
|
|
||||||
// create destination address
|
struct ifaliasreq inreq;
|
||||||
fGateway.sin_family = AF_INET;
|
memset(&inreq, 0, sizeof(struct ifaliasreq));
|
||||||
if(fPeerRequests.address != INADDR_ANY)
|
memcpy(inreq.ifra_name, Interface().Name(), IF_NAMESIZE);
|
||||||
fGateway.sin_addr.s_addr = fPeerRequests.address;
|
memcpy(&inreq.ifra_addr, &newAddr, sizeof(struct sockaddr));
|
||||||
else if(fPeerConfiguration.address == INADDR_ANY)
|
memcpy(&inreq.ifra_mask, &netmask, sizeof(struct sockaddr));
|
||||||
fGateway.sin_addr.s_addr = 0x020F0F0F; // was: INADDR_BROADCAST
|
memcpy(&inreq.ifra_broadaddr, &broadaddr, sizeof(struct sockaddr));
|
||||||
else
|
inreq.ifra_index = -1;
|
||||||
fGateway.sin_addr.s_addr = fPeerConfiguration.address;
|
// create a new interface address
|
||||||
fGateway.sin_len = sizeof(struct sockaddr_in);
|
// Is it OK when we already have one?
|
||||||
memcpy(&inreq.ifra_dstaddr, &fGateway,
|
// test case: ifconfig ppp up
|
||||||
sizeof(struct sockaddr_in));
|
// ifconfig ppp down
|
||||||
memcpy(&ifreqDestination.ifr_dstaddr, &inreq.ifra_dstaddr,
|
// ifconfig ppp up
|
||||||
sizeof(struct sockaddr_in));
|
// check if some weird things happen
|
||||||
|
|
||||||
// create netmask
|
net_domain* domain = sStackModule->get_domain(AF_INET);
|
||||||
inreq.ifra_mask.sin_family = AF_INET;
|
status_t status = set_interface_address(domain, &inreq);
|
||||||
inreq.ifra_mask.sin_addr.s_addr = fLocalRequests.netmask;
|
|
||||||
inreq.ifra_mask.sin_len = sizeof(struct sockaddr_in);
|
|
||||||
|
|
||||||
// tell stack to use these values
|
if (status != B_OK) {
|
||||||
if(in_control(NULL, SIOCAIFADDR, (caddr_t) &inreq,
|
TRACE("%s:%s: set_interface_address Fail!!!!\n", __FILE__, __func__);
|
||||||
Interface().Ifnet()) != B_OK)
|
return;
|
||||||
ERROR("IPCP: UpdateAddress(): SIOCAIFADDR returned error!\n");
|
}
|
||||||
if(in_control(NULL, SIOCSIFADDR, (caddr_t) &ifreqAddress,
|
TRACE("%s:%s: set_interface_address fine\n", __FILE__, __func__);
|
||||||
Interface().Ifnet()) != B_OK)
|
|
||||||
ERROR("IPCP: UpdateAddress(): SIOCSIFADDR returned error!\n");
|
|
||||||
if(in_control(NULL, SIOCSIFDSTADDR, (caddr_t) &ifreqDestination,
|
net_interface* pppInterface = get_interface_by_name(domain, Interface().Name());
|
||||||
Interface().Ifnet()) != B_OK)
|
if (pppInterface == NULL) {
|
||||||
ERROR("IPCP: UpdateAddress(): SIOCSIFDSTADDR returned error!\n");
|
TRACE("%s::%s: pppInterface not found!\n", __FILE__, __func__);
|
||||||
memcpy(&inreq.ifra_addr, &inreq.ifra_mask, sizeof(struct sockaddr_in));
|
return;
|
||||||
// SIOCISFNETMASK wants the netmask to be in ifra_addr
|
}
|
||||||
if(in_control(NULL, SIOCSIFNETMASK, (caddr_t) &inreq,
|
|
||||||
Interface().Ifnet()) != B_OK)
|
net_interface_address* pppInterfaceAddress = NULL;
|
||||||
ERROR("IPCP: UpdateAddress(): SIOCSIFNETMASK returned error!\n");
|
while (sDatalinkModule->get_next_interface_address(pppInterface,
|
||||||
|
&pppInterfaceAddress)) {
|
||||||
|
if (pppInterfaceAddress->domain->family != AF_INET)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// add default/subnet route
|
// add default/subnet route
|
||||||
if(Side() == PPP_LOCAL_SIDE) {
|
if (Side() == PPP_LOCAL_SIDE && pppInterfaceAddress != NULL) {
|
||||||
if(rtrequest(RTM_ADD, (struct sockaddr*) &inreq.ifra_mask,
|
struct sockaddr addrGateway = {8, AF_INET, {0x00, 0x00, 0x00, 0x00,
|
||||||
(struct sockaddr*) &fGateway, (struct sockaddr*) &inreq.ifra_mask,
|
0x00, 0x00} };
|
||||||
RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK)
|
|
||||||
ERROR("IPCP: UpdateAddress(): could not add default/subnet route!\n");
|
|
||||||
|
|
||||||
--fDefaultRoute->rt_refcnt;
|
// create destination address
|
||||||
|
if (fPeerRequests.address != INADDR_ANY)
|
||||||
|
memcpy(addrGateway.sa_data + 2, &fPeerRequests.address,
|
||||||
|
sizeof(in_addr_t));
|
||||||
|
else if (fPeerConfiguration.address == INADDR_ANY) {
|
||||||
|
in_addr_t gateway = 0x020F0F0F;
|
||||||
|
memcpy(addrGateway.sa_data + 2, &gateway, sizeof(in_addr_t));
|
||||||
|
// was: INADDR_BROADCAST
|
||||||
|
} else
|
||||||
|
memcpy(addrGateway.sa_data + 2, &fPeerConfiguration.address,
|
||||||
|
sizeof(in_addr_t));
|
||||||
|
|
||||||
|
net_route defaultRoute;
|
||||||
|
defaultRoute.destination = NULL;
|
||||||
|
defaultRoute.mask = NULL;
|
||||||
|
defaultRoute.gateway = &addrGateway;
|
||||||
|
defaultRoute.flags = RTF_DEFAULT | RTF_GATEWAY;
|
||||||
|
defaultRoute.interface_address = pppInterfaceAddress;
|
||||||
|
// route->interface_address;
|
||||||
|
|
||||||
|
status_t status = sDatalinkModule->add_route(domain, &defaultRoute);
|
||||||
|
if (status == B_OK)
|
||||||
|
dprintf("%s::%s: add route default OK!\n", __FILE__, __func__);
|
||||||
|
else
|
||||||
|
dprintf("%s::%s: add route default Fail!\n", __FILE__, __func__);
|
||||||
|
|
||||||
|
sDatalinkModule->put_interface_address(pppInterfaceAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Side() == PPP_LOCAL_SIDE) {
|
||||||
|
int file;
|
||||||
|
int primary_dns, secondary_dns;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
file = open(RESOLV_CONF_FILE, O_RDWR);
|
||||||
|
|
||||||
|
primary_dns = ntohl(fLocalConfiguration.primaryDNS);
|
||||||
|
secondary_dns = ntohl(fLocalConfiguration.secondaryDNS);
|
||||||
|
|
||||||
|
sprintf(buf, "%s\t%d.%d.%d.%d\n%s\t%d.%d.%d.%d\n",
|
||||||
|
"nameserver",
|
||||||
|
(primary_dns & 0xff000000) >> 24,
|
||||||
|
(primary_dns & 0x00ff0000) >> 16,
|
||||||
|
(primary_dns & 0x0000ff00) >> 8,
|
||||||
|
(primary_dns & 0x000000ff),
|
||||||
|
"nameserver",
|
||||||
|
(secondary_dns & 0xff000000) >> 24,
|
||||||
|
(secondary_dns & 0x00ff0000) >> 16,
|
||||||
|
(secondary_dns & 0x0000ff00) >> 8,
|
||||||
|
(secondary_dns & 0x000000ff));
|
||||||
|
|
||||||
|
write(file, buf, strlen(buf));
|
||||||
|
close(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,7 +576,57 @@ IPCP::UpdateAddresses()
|
|||||||
void
|
void
|
||||||
IPCP::RemoveRoutes()
|
IPCP::RemoveRoutes()
|
||||||
{
|
{
|
||||||
// note: netstack creates and deletes destination route automatically
|
// note:
|
||||||
|
// haiku supports multi default route. But for Desktop, ppp is generally
|
||||||
|
// the only default route. So is it necessary to remove other default
|
||||||
|
// route?
|
||||||
|
TRACE("%s::%s: entering RemoveRoutes!\n", __FILE__, __func__);
|
||||||
|
|
||||||
|
char *ethernetName = NULL;
|
||||||
|
PPPoEDevice* pppoeDevice = (PPPoEDevice *)Interface().Device();
|
||||||
|
if (pppoeDevice == NULL)
|
||||||
|
return;
|
||||||
|
ethernetName = pppoeDevice->EthernetIfnet()->name;
|
||||||
|
if (ethernetName == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
net_domain* domain = sStackModule->get_domain(AF_INET);
|
||||||
|
net_interface* pppInterface = get_interface_by_name(domain, ethernetName);
|
||||||
|
|
||||||
|
if (pppInterface == NULL) {
|
||||||
|
TRACE("%s::%s: pppInterface not found!\n", __FILE__, __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_interface_address* pppInterfaceAddress = NULL;
|
||||||
|
|
||||||
|
while (sDatalinkModule->get_next_interface_address(pppInterface,
|
||||||
|
&pppInterfaceAddress)) {
|
||||||
|
if (pppInterfaceAddress->domain->family != AF_INET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
net_route oldDefaultRoute;
|
||||||
|
oldDefaultRoute.destination = NULL;
|
||||||
|
oldDefaultRoute.mask = NULL;
|
||||||
|
oldDefaultRoute.gateway = NULL;
|
||||||
|
oldDefaultRoute.flags= RTF_DEFAULT;
|
||||||
|
oldDefaultRoute.interface_address = pppInterfaceAddress;
|
||||||
|
|
||||||
|
status_t status = sDatalinkModule->remove_route(domain, &oldDefaultRoute);
|
||||||
|
// current: can not get the system default route so we fake
|
||||||
|
// one default route for delete
|
||||||
|
// Todo: save the oldDefaultRoute to fDefaultRoute
|
||||||
|
// restore the fDefaultRoute when ppp is down
|
||||||
|
|
||||||
|
sDatalinkModule->put_interface_address(pppInterfaceAddress);
|
||||||
|
|
||||||
|
if (status == B_OK)
|
||||||
|
dprintf("IPCP::RemoveRoutes: remove old default route OK!\n");
|
||||||
|
else
|
||||||
|
dprintf("IPCP::RemoveRoutes: remove old default route Fail!\n");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (fDefaultRoute) {
|
if (fDefaultRoute) {
|
||||||
struct sockaddr_in netmask;
|
struct sockaddr_in netmask;
|
||||||
@@ -484,9 +636,9 @@ IPCP::RemoveRoutes()
|
|||||||
netmask.sin_addr.s_addr = fLocalRequests.netmask;
|
netmask.sin_addr.s_addr = fLocalRequests.netmask;
|
||||||
netmask.sin_len = sizeof(struct sockaddr_in);
|
netmask.sin_len = sizeof(struct sockaddr_in);
|
||||||
|
|
||||||
if(rtrequest(RTM_DELETE, (struct sockaddr*) &netmask,
|
// if (rtrequest(RTM_DELETE, (struct sockaddr*) &netmask,
|
||||||
(struct sockaddr*) &fGateway, (struct sockaddr*) &netmask,
|
// (struct sockaddr*) &fGateway, (struct sockaddr*) &netmask,
|
||||||
RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK)
|
// RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK)
|
||||||
ERROR("IPCP: RemoveRoutes(): could not remove default/subnet route!\n");
|
ERROR("IPCP: RemoveRoutes(): could not remove default/subnet route!\n");
|
||||||
|
|
||||||
fDefaultRoute = NULL;
|
fDefaultRoute = NULL;
|
||||||
@@ -571,7 +723,7 @@ IPCP::TOBadEvent()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RCREvent(struct mbuf *packet)
|
IPCP::RCREvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RCREvent() state=%d\n", State());
|
TRACE("IPCP: RCREvent() state=%d\n", State());
|
||||||
|
|
||||||
@@ -579,8 +731,13 @@ IPCP::RCREvent(struct mbuf *packet)
|
|||||||
KPPPConfigurePacket nak(PPP_CONFIGURE_NAK);
|
KPPPConfigurePacket nak(PPP_CONFIGURE_NAK);
|
||||||
KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT);
|
KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT);
|
||||||
|
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &lcpHeader = bufferheader.Data();
|
||||||
|
|
||||||
// we should not use the same id as the peer
|
// we should not use the same id as the peer
|
||||||
if(fID == mtod(packet, ppp_lcp_packet*)->id)
|
if (fID == lcpHeader.id)
|
||||||
fID -= 128;
|
fID -= 128;
|
||||||
|
|
||||||
nak.SetID(request.ID());
|
nak.SetID(request.ID());
|
||||||
@@ -620,7 +777,7 @@ IPCP::RCREvent(struct mbuf *packet)
|
|||||||
case IPCP_SECONDARY_DNS:
|
case IPCP_SECONDARY_DNS:
|
||||||
if (item->length != 6) {
|
if (item->length != 6) {
|
||||||
// the packet is invalid
|
// the packet is invalid
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
NewState(PPP_INITIAL_STATE);
|
NewState(PPP_INITIAL_STATE);
|
||||||
ReportUpFailedEvent();
|
ReportUpFailedEvent();
|
||||||
return;
|
return;
|
||||||
@@ -630,7 +787,7 @@ IPCP::RCREvent(struct mbuf *packet)
|
|||||||
if (*wishedAddress == INADDR_ANY) {
|
if (*wishedAddress == INADDR_ANY) {
|
||||||
if (*requestedAddress == INADDR_ANY) {
|
if (*requestedAddress == INADDR_ANY) {
|
||||||
// we do not have an address for you
|
// we do not have an address for you
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
NewState(PPP_INITIAL_STATE);
|
NewState(PPP_INITIAL_STATE);
|
||||||
ReportUpFailedEvent();
|
ReportUpFailedEvent();
|
||||||
return;
|
return;
|
||||||
@@ -665,19 +822,18 @@ IPCP::RCREvent(struct mbuf *packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nak.CountItems() > 0) {
|
if (nak.CountItems() > 0) {
|
||||||
RCRBadEvent(nak.ToMbuf(Interface().MRU(), Interface().PacketOverhead()), NULL);
|
RCRBadEvent(nak.ToNetBuffer(Interface().MRU()), NULL);
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
} else if (reject.CountItems() > 0) {
|
} else if (reject.CountItems() > 0) {
|
||||||
RCRBadEvent(NULL, reject.ToMbuf(Interface().MRU(),
|
RCRBadEvent(NULL, reject.ToNetBuffer(Interface().MRU()));
|
||||||
Interface().PacketOverhead()));
|
gBufferModule->free(packet);
|
||||||
m_freem(packet);
|
|
||||||
} else
|
} else
|
||||||
RCRGoodEvent(packet);
|
RCRGoodEvent(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RCRGoodEvent(struct mbuf *packet)
|
IPCP::RCRGoodEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RCRGoodEvent() state=%d\n", State());
|
TRACE("IPCP: RCRGoodEvent() state=%d\n", State());
|
||||||
|
|
||||||
@@ -709,16 +865,36 @@ IPCP::RCRGoodEvent(struct mbuf *packet)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
IPCP::RCRBadEvent(net_buffer *nak, net_buffer *reject)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RCRBadEvent() state=%d\n", State());
|
TRACE("IPCP: RCRBadEvent() state=%d\n", State());
|
||||||
|
|
||||||
|
uint16 lcpHdrRejectLength = 0;
|
||||||
|
uint16 lcpHdrNakLength = 0;
|
||||||
|
|
||||||
|
if (nak) {
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> nakBufferHeaderReader(nak);
|
||||||
|
if (nakBufferHeaderReader.Status() != B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &lcpNakPacket = nakBufferHeaderReader.Data();
|
||||||
|
lcpHdrNakLength = lcpNakPacket.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (reject) {
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> rejectBufferHeaderReader(reject);
|
||||||
|
if (rejectBufferHeaderReader.Status() != B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &lcpRejectPacket = rejectBufferHeaderReader.Data();
|
||||||
|
lcpHdrRejectLength = lcpRejectPacket.length;
|
||||||
|
}
|
||||||
|
|
||||||
switch (State()) {
|
switch (State()) {
|
||||||
case PPP_OPENED_STATE:
|
case PPP_OPENED_STATE:
|
||||||
NewState(PPP_REQ_SENT_STATE);
|
NewState(PPP_REQ_SENT_STATE);
|
||||||
@@ -732,9 +908,9 @@ IPCP::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
|||||||
case PPP_INITIAL_STATE:
|
case PPP_INITIAL_STATE:
|
||||||
case PPP_REQ_SENT_STATE:
|
case PPP_REQ_SENT_STATE:
|
||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
if(nak && ntohs(mtod(nak, ppp_lcp_packet*)->length) > 3)
|
if (nak && ntohs(lcpHdrNakLength) > 3)
|
||||||
SendConfigureNak(nak);
|
SendConfigureNak(nak);
|
||||||
else if(reject && ntohs(mtod(reject, ppp_lcp_packet*)->length) > 3)
|
else if (reject && ntohs(lcpHdrRejectLength) > 3)
|
||||||
SendConfigureNak(reject);
|
SendConfigureNak(reject);
|
||||||
return;
|
return;
|
||||||
// prevents the nak/reject from being m_freem()'d
|
// prevents the nak/reject from being m_freem()'d
|
||||||
@@ -744,22 +920,26 @@ IPCP::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nak)
|
if (nak)
|
||||||
m_freem(nak);
|
gBufferModule->free(nak);
|
||||||
if (reject)
|
if (reject)
|
||||||
m_freem(reject);
|
gBufferModule->free(reject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RCAEvent(struct mbuf *packet)
|
IPCP::RCAEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RCAEvent() state=%d\n", State());
|
ERROR("IPCP: RCAEvent() 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 &lcpHeader = bufferheader.Data();
|
||||||
|
if (fRequestID != lcpHeader.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,20 +1029,25 @@ IPCP::RCAEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RCNEvent(struct mbuf *packet)
|
IPCP::RCNEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RCNEvent() state=%d\n", State());
|
TRACE("IPCP: RCNEvent() 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 &lcpHeader = bufferheader.Data();
|
||||||
|
|
||||||
|
if (fRequestID != lcpHeader.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,7 +1120,7 @@ IPCP::RCNEvent(struct mbuf *packet)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// DNS and addresses must be supported if we set them to auto
|
// DNS and addresses must be supported if we set them to auto
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
NewState(PPP_INITIAL_STATE);
|
NewState(PPP_INITIAL_STATE);
|
||||||
ReportUpFailedEvent();
|
ReportUpFailedEvent();
|
||||||
return;
|
return;
|
||||||
@@ -962,17 +1147,22 @@ IPCP::RCNEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RTREvent(struct mbuf *packet)
|
IPCP::RTREvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RTREvent() state=%d\n", State());
|
TRACE("IPCP: RTREvent() state=%d\n", State());
|
||||||
|
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &lcpHeader = bufferheader.Data();
|
||||||
|
|
||||||
// we should not use the same ID as the peer
|
// we should not use the same ID as the peer
|
||||||
if(fID == mtod(packet, ppp_lcp_packet*)->id)
|
if (fID == lcpHeader.id)
|
||||||
fID -= 128;
|
fID -= 128;
|
||||||
|
|
||||||
switch (State()) {
|
switch (State()) {
|
||||||
@@ -988,33 +1178,37 @@ IPCP::RTREvent(struct mbuf *packet)
|
|||||||
case PPP_REQ_SENT_STATE:
|
case PPP_REQ_SENT_STATE:
|
||||||
SendTerminateAck(packet);
|
SendTerminateAck(packet);
|
||||||
return;
|
return;
|
||||||
// do not m_freem() packet
|
// do not free packet
|
||||||
|
|
||||||
case PPP_OPENED_STATE:
|
case PPP_OPENED_STATE:
|
||||||
NewState(PPP_CLOSING_STATE);
|
NewState(PPP_CLOSING_STATE);
|
||||||
ResetRestartCount();
|
ResetRestartCount();
|
||||||
SendTerminateAck(packet);
|
SendTerminateAck(packet);
|
||||||
return;
|
return;
|
||||||
// do not m_freem() packet
|
// do not free packet
|
||||||
|
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RTAEvent(struct mbuf *packet)
|
IPCP::RTAEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RTAEvent() state=%d\n", State());
|
TRACE("IPCP: RTAEvent() state=%d\n", State());
|
||||||
|
|
||||||
if(fTerminateID != mtod(packet, ppp_lcp_packet*)->id) {
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &lcpHeader = bufferheader.Data();
|
||||||
|
if (fTerminateID != lcpHeader.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,12 +1235,12 @@ IPCP::RTAEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RUCEvent(struct mbuf *packet)
|
IPCP::RUCEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RUCEvent() state=%d\n", State());
|
TRACE("IPCP: RUCEvent() state=%d\n", State());
|
||||||
|
|
||||||
@@ -1055,7 +1249,7 @@ IPCP::RUCEvent(struct mbuf *packet)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IPCP::RXJBadEvent(struct mbuf *packet)
|
IPCP::RXJBadEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: RXJBadEvent() state=%d\n", State());
|
TRACE("IPCP: RXJBadEvent() state=%d\n", State());
|
||||||
|
|
||||||
@@ -1086,7 +1280,7 @@ IPCP::RXJBadEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1128,7 +1322,9 @@ IPCP::ReportDownEvent()
|
|||||||
memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration));
|
memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration));
|
||||||
memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration));
|
memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration));
|
||||||
|
|
||||||
UpdateAddresses();
|
// don't update address if connect on demand is enabled
|
||||||
|
dprintf("ppp down, and leaving old address and rotues\n");
|
||||||
|
// UpdateAddresses();
|
||||||
|
|
||||||
DownEvent();
|
DownEvent();
|
||||||
}
|
}
|
||||||
@@ -1169,12 +1365,12 @@ IPCP::SendConfigureRequest()
|
|||||||
// add address
|
// add address
|
||||||
ipItem.type = IPCP_ADDRESS;
|
ipItem.type = IPCP_ADDRESS;
|
||||||
if (fLocalRequests.address == INADDR_ANY)
|
if (fLocalRequests.address == INADDR_ANY)
|
||||||
ipItem.address = fLocalConfiguration.address;
|
ipItem.address = (fLocalConfiguration.address);
|
||||||
else
|
else
|
||||||
ipItem.address = fLocalRequests.address;
|
ipItem.address =(fLocalRequests.address);
|
||||||
request.AddItem((ppp_configure_item*) &ipItem);
|
request.AddItem((ppp_configure_item*) &ipItem);
|
||||||
|
|
||||||
TRACE("IPCP: SCR: confaddr=%lX; reqaddr=%lX; addr=%lX\n",
|
TRACE("IPCP: SCR: confaddr=%X; reqaddr=%X; addr=%X\n",
|
||||||
fLocalConfiguration.address, fLocalRequests.address,
|
fLocalConfiguration.address, fLocalRequests.address,
|
||||||
((ip_item*)request.ItemAt(0))->address);
|
((ip_item*)request.ItemAt(0))->address);
|
||||||
|
|
||||||
@@ -1196,20 +1392,26 @@ IPCP::SendConfigureRequest()
|
|||||||
|
|
||||||
// TODO: add VJC support
|
// TODO: add VJC support
|
||||||
|
|
||||||
return Send(request.ToMbuf(Interface().MRU(),
|
return Send(request.ToNetBuffer(Interface().MRU())) == B_OK;
|
||||||
Interface().PacketOverhead())) == B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IPCP::SendConfigureAck(struct mbuf *packet)
|
IPCP::SendConfigureAck(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: SendConfigureAck() state=%d\n", State());
|
TRACE("IPCP: SendConfigureAck() state=%d\n", State());
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mtod(packet, ppp_lcp_packet*)->code = PPP_CONFIGURE_ACK;
|
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return false;
|
||||||
|
ppp_lcp_packet &lcpheader = bufferheader.Data();
|
||||||
|
lcpheader.code = PPP_CONFIGURE_ACK;
|
||||||
|
|
||||||
|
bufferheader.Sync();
|
||||||
|
|
||||||
KPPPConfigurePacket ack(packet);
|
KPPPConfigurePacket ack(packet);
|
||||||
|
|
||||||
// verify items
|
// verify items
|
||||||
@@ -1271,22 +1473,29 @@ IPCP::SendConfigureAck(struct mbuf *packet)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IPCP::SendConfigureNak(struct mbuf *packet)
|
IPCP::SendConfigureNak(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: SendConfigureNak() state=%d\n", State());
|
TRACE("IPCP: SendConfigureNak() 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);
|
||||||
if(nak->code == PPP_CONFIGURE_NAK) {
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ppp_lcp_packet &nak = bufferheader.Data();
|
||||||
|
|
||||||
|
if (nak.code == PPP_CONFIGURE_NAK) {
|
||||||
if (fNakCounter == 0) {
|
if (fNakCounter == 0) {
|
||||||
// We sent enough naks. Let's try a reject.
|
// We sent enough naks. Let's try a reject.
|
||||||
nak->code = PPP_CONFIGURE_REJECT;
|
nak.code = PPP_CONFIGURE_REJECT;
|
||||||
} else
|
} else
|
||||||
--fNakCounter;
|
--fNakCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bufferheader.Sync();
|
||||||
|
|
||||||
return Send(packet) == B_OK;
|
return Send(packet) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1299,81 +1508,78 @@ IPCP::SendTerminateRequest()
|
|||||||
--fTerminateCounter;
|
--fTerminateCounter;
|
||||||
fNextTimeout = system_time() + kIPCPStateMachineTimeout;
|
fNextTimeout = system_time() + kIPCPStateMachineTimeout;
|
||||||
|
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
net_buffer *packet = gBufferModule->create(256);
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
packet->m_pkthdr.len = packet->m_len = 4;
|
ppp_lcp_packet *request;
|
||||||
|
status_t status = gBufferModule->append_size(packet, 1492, (void **)(&request));
|
||||||
|
if (status != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
// reserve some space for other protocols
|
|
||||||
packet->m_data += Interface().PacketOverhead();
|
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
|
||||||
request->code = PPP_TERMINATE_REQUEST;
|
request->code = PPP_TERMINATE_REQUEST;
|
||||||
request->id = fTerminateID = NextID();
|
request->id = fTerminateID = NextID();
|
||||||
request->length = htons(4);
|
request->length = htons(4);
|
||||||
|
|
||||||
|
status = gBufferModule->trim(packet, 4);
|
||||||
|
if (status != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
return Send(packet) == B_OK;
|
return Send(packet) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IPCP::SendTerminateAck(struct mbuf *request)
|
IPCP::SendTerminateAck(net_buffer *request)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: SendTerminateAck() state=%d\n", State());
|
TRACE("IPCP: SendTerminateAck() state=%d\n", State());
|
||||||
|
|
||||||
struct mbuf *reply = request;
|
net_buffer *reply = request;
|
||||||
|
|
||||||
ppp_lcp_packet *ack;
|
|
||||||
|
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
reply = m_gethdr(MT_DATA);
|
reply = gBufferModule->create(256);
|
||||||
if(!reply)
|
ppp_lcp_packet *ack;
|
||||||
|
status_t status = gBufferModule->append_size(reply, 1492, (void **)(&ack));
|
||||||
|
if (status != B_OK) {
|
||||||
|
gBufferModule->free(reply);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
reply->m_data += Interface().PacketOverhead();
|
|
||||||
reply->m_pkthdr.len = reply->m_len = 4;
|
|
||||||
|
|
||||||
ack = mtod(reply, ppp_lcp_packet*);
|
|
||||||
ack->id = NextID();
|
ack->id = NextID();
|
||||||
} else
|
|
||||||
ack = mtod(reply, ppp_lcp_packet*);
|
|
||||||
|
|
||||||
ack->code = PPP_TERMINATE_ACK;
|
ack->code = PPP_TERMINATE_ACK;
|
||||||
ack->length = htons(4);
|
ack->length = htons(4);
|
||||||
|
gBufferModule->trim(reply, 4);
|
||||||
|
} else {
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(reply);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return false;
|
||||||
|
ppp_lcp_packet &ack = bufferHeader.Data();
|
||||||
|
ack.code = PPP_TERMINATE_ACK;
|
||||||
|
ack.length = htons(4);
|
||||||
|
}
|
||||||
|
|
||||||
return Send(reply) == B_OK;
|
return Send(reply) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IPCP::SendCodeReject(struct mbuf *packet)
|
IPCP::SendCodeReject(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("IPCP: SendCodeReject() state=%d\n", State());
|
TRACE("IPCP: SendCodeReject() state=%d\n", State());
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
M_PREPEND(packet, 4);
|
NetBufferPrepend<ppp_lcp_packet> bufferHeader(packet);
|
||||||
// add some space for the header
|
if (bufferHeader.Status() != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
// adjust packet if too big
|
ppp_lcp_packet &reject = bufferHeader.Data();
|
||||||
int32 adjust = Interface().MRU();
|
|
||||||
if(packet->m_flags & M_PKTHDR) {
|
|
||||||
adjust -= packet->m_pkthdr.len;
|
|
||||||
} else
|
|
||||||
adjust -= packet->m_len;
|
|
||||||
|
|
||||||
if(adjust < 0)
|
reject.code = PPP_CODE_REJECT;
|
||||||
m_adj(packet, adjust);
|
reject.id = NextID();
|
||||||
|
reject.length = htons(packet->size);
|
||||||
|
|
||||||
ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
|
bufferHeader.Sync();
|
||||||
reject->code = PPP_CODE_REJECT;
|
|
||||||
reject->id = NextID();
|
|
||||||
if(packet->m_flags & M_PKTHDR)
|
|
||||||
reject->length = htons(packet->m_pkthdr.len);
|
|
||||||
else
|
|
||||||
reject->length = htons(packet->m_len);
|
|
||||||
|
|
||||||
return Send(packet) == B_OK;
|
return Send(packet) == B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -71,10 +73,10 @@ class IPCP : public KPPPProtocol {
|
|||||||
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:
|
||||||
@@ -90,15 +92,15 @@ class IPCP : public KPPPProtocol {
|
|||||||
// 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);
|
||||||
@@ -108,11 +110,11 @@ 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;
|
||||||
@@ -120,14 +122,14 @@ class IPCP : public KPPPProtocol {
|
|||||||
|
|
||||||
// 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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
@@ -75,14 +78,20 @@ 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) {
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
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:
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel network ppp pap ;
|
SubDir HAIKU_TOP src add-ons kernel network ppp pap ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
if $(TARGET_PLATFORM) != haiku {
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
# for kernel_cpp.h and BLocker
|
UsePrivateKernelHeaders ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
UsePrivateHeaders [ FDirName kernel ] ;
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
libkernelppp headers ] : true ;
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
SubDirC++Flags -fno-rtti ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
KernelAddon pap :
|
KernelAddon pap :
|
||||||
pap.cpp
|
pap.cpp
|
||||||
Protocol.cpp
|
Protocol.cpp
|
||||||
@@ -31,5 +25,5 @@ LinkAgainst pap : libkernelppp.a ;
|
|||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
HaikuInstall install-networking
|
HaikuInstall install-networking
|
||||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
: /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||||
: pap ;
|
: pap ;
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
#include <sys/sockio.h>
|
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
static const bigtime_t kPAPTimeout = 3000000;
|
static const bigtime_t kPAPTimeout = 3000000;
|
||||||
// 3 seconds
|
// 3 seconds
|
||||||
@@ -34,6 +34,14 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -159,16 +167,18 @@ PAP::Down()
|
|||||||
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -176,31 +186,30 @@ PAP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
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(length)
|
|
||||||
m_adj(packet, -length);
|
|
||||||
|
|
||||||
if(ntohs(data->length) < 4)
|
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;
|
||||||
@@ -320,19 +329,22 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,15 +369,19 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,20 +397,24 @@ PAP::RAEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +430,7 @@ PAP::RNEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -429,68 +449,72 @@ PAP::SendRequest()
|
|||||||
--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);
|
||||||
|
// 6 : lcp header 4 byte + username length 1 byte + password length 1 byte
|
||||||
|
|
||||||
packet->m_pkthdr.len = packet->m_len = 6 + strlen(username) + strlen(password);
|
|
||||||
|
|
||||||
// reserve some space for overhead (we are lazy and reserve too much)
|
|
||||||
packet->m_data += Interface().PacketOverhead();
|
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
|
||||||
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->data[0] = 0;
|
ack.code = PPP_CONFIGURE_ACK;
|
||||||
|
ack.length = htons(5);
|
||||||
|
ack.data[0] = 0;
|
||||||
|
gBufferModule->trim(packet, 5);
|
||||||
|
|
||||||
|
bufferheader.Sync();
|
||||||
|
|
||||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class PAPHandler : public KPPPOptionHandler {
|
|||||||
{ 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);
|
||||||
|
|
||||||
@@ -57,8 +58,8 @@ class PAP : public KPPPProtocol {
|
|||||||
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:
|
||||||
@@ -70,9 +71,9 @@ class PAP : public KPPPProtocol {
|
|||||||
// 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();
|
||||||
@@ -80,13 +81,13 @@ class PAP : public KPPPProtocol {
|
|||||||
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;
|
||||||
|
|||||||
@@ -5,23 +5,22 @@
|
|||||||
|
|
||||||
#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)
|
||||||
{
|
{
|
||||||
@@ -62,12 +61,18 @@ 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:
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel network ppp ppp ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
|
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||||
|
# Needed for <support/Errors.h> and maybe other stuff.
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
|
# We need the public network headers also when not compiling for Haiku.
|
||||||
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
|
UsePrivateHeaders net ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
KernelAddon ppp :
|
||||||
|
ppp.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
HaikuInstall install-networking :
|
||||||
|
/boot/home/config/add-ons/kernel/network/ppp
|
||||||
|
: ppp ;
|
||||||
@@ -0,0 +1,388 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Lin Longzhou, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net/if_media.h>
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <ethernet.h>
|
||||||
|
#include <ether_driver.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_datalink_protocol.h>
|
||||||
|
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <KPPPManager.h>
|
||||||
|
#include <ppp_device.h>
|
||||||
|
|
||||||
|
#define PPP_HEADER_LENGTH (8 + ETHER_HEADER_LENGTH)
|
||||||
|
|
||||||
|
|
||||||
|
net_buffer* create_buffer_for_frame(uint8 *frame, uint16 frame_size);
|
||||||
|
|
||||||
|
static const bigtime_t kLinkCheckInterval = 1000000;
|
||||||
|
// 1 second
|
||||||
|
|
||||||
|
net_buffer_module_info *gBufferModule;
|
||||||
|
ppp_interface_module_info* gPPPInterfaceModule;
|
||||||
|
static net_stack_module_info *sStackModule;
|
||||||
|
|
||||||
|
static mutex sListLock;
|
||||||
|
static DoublyLinkedList<ppp_device> sCheckList;
|
||||||
|
static sem_id sLinkChangeSemaphore;
|
||||||
|
static thread_id sLinkCheckerThread;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
//
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_init(const char *name, net_device **_device)
|
||||||
|
{
|
||||||
|
// ppp device
|
||||||
|
dprintf("%s: entering!\n", __func__);
|
||||||
|
|
||||||
|
if (strncmp(name, "ppp", 3)) {
|
||||||
|
dprintf("[%s] not ppp device\n", name);
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("[%s] is ppp device\n", name);
|
||||||
|
|
||||||
|
status_t status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// ppp_device *device = new (std::nothrow) ppp_device;
|
||||||
|
ppp_interface_id idInterface = gPPPInterfaceModule->CreateInterfaceWithName(name, 0);
|
||||||
|
KPPPInterface * pppInterface = gPPPInterfaceModule->GetInterface(idInterface);
|
||||||
|
|
||||||
|
if (idInterface <= 0 || pppInterface == NULL) {
|
||||||
|
if (idInterface <= 0)
|
||||||
|
dprintf("%s: idInterface:%ld\n", __func__, idInterface);
|
||||||
|
else
|
||||||
|
dprintf("%s: pppInterface == NULL %ld\n", __func__, idInterface);
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ifnet available until interface up phase
|
||||||
|
ppp_device *device = (ppp_device *)pppInterface->Ifnet();
|
||||||
|
if (device == NULL) {
|
||||||
|
dprintf("%s: can not get ppp_device\n", __func__);
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(device->name, name);
|
||||||
|
device->flags = (IFF_BROADCAST | IFF_LINK) & (~IFF_UP);
|
||||||
|
device->type = IFT_PPP;
|
||||||
|
device->mtu = 1492;
|
||||||
|
device->frame_size = 1500;
|
||||||
|
device->media = IFM_ACTIVE | IFM_ETHER;
|
||||||
|
device->header_length = PPP_HEADER_LENGTH;
|
||||||
|
|
||||||
|
status =sStackModule->init_fifo(&(device->ppp_fifo), "ppp_fifo", 10 * 1500);
|
||||||
|
// 10 ppp packet at most
|
||||||
|
if (status < B_OK)
|
||||||
|
return(status);
|
||||||
|
|
||||||
|
TRACE("[%s] finish\n", "allocate ppp_device");
|
||||||
|
*_device = device;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_uninit(net_device *device)
|
||||||
|
{
|
||||||
|
dprintf("%s: uninit ppp\n", __func__);
|
||||||
|
ppp_device *ppp_dev=(ppp_device *)device;
|
||||||
|
|
||||||
|
sStackModule->uninit_fifo(&(ppp_dev->ppp_fifo));
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
|
||||||
|
// delete ppp_dev->KPPP_Interface;
|
||||||
|
delete ppp_dev;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_up(net_device *_device)
|
||||||
|
{
|
||||||
|
dprintf("ppp_up\n");
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (device->KPPP_Interface == NULL) {
|
||||||
|
dprintf("%s: warning! can not find pppinterface KPPP_Interface\n", __func__);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->KPPP_Interface->Up() != true) {
|
||||||
|
dprintf("%s: warning! KPPP_Interface->Up() failure\n", __func__);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
device->mtu = device->frame_size - device->header_length;
|
||||||
|
// s_pppoe_dev = device;
|
||||||
|
|
||||||
|
dprintf("%s: congratulations! Find pppinterface (device->KPPP_Interface)\n", __func__);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ppp_down(net_device *_device)
|
||||||
|
{
|
||||||
|
dprintf("%s\n", __func__);
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
device->KPPP_Interface->Down();
|
||||||
|
|
||||||
|
MutexLocker _(sListLock);
|
||||||
|
|
||||||
|
// if the device is still part of the list, remove it
|
||||||
|
if (device->GetDoublyLinkedListLink()->next != NULL
|
||||||
|
|| device->GetDoublyLinkedListLink()->previous != NULL
|
||||||
|
|| device == sCheckList.Head())
|
||||||
|
sCheckList.Remove(device);
|
||||||
|
|
||||||
|
// device->KPPP_Interface = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_control(net_device *_device, int32 op, void *argument,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
TRACE("%s %ld\n", __func__, op);
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (device->KPPP_Interface == NULL) {
|
||||||
|
dprintf("%s: can not find KPPP_Interface for ppp\n", __func__);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return device->KPPP_Interface->Control(op, argument, length);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_send_data(net_device *_device, net_buffer *buffer)
|
||||||
|
{
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (buffer->size > device->frame_size || buffer->size < device->header_length) {
|
||||||
|
device->stats.send.errors++;
|
||||||
|
dprintf("sorry! fail send ppp packet, size wrong!\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->KPPP_Interface == NULL) {
|
||||||
|
device->stats.send.errors++;
|
||||||
|
dprintf("Fail send ppp packet, no eth for ppp!\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t net_buffer_size = buffer->size;
|
||||||
|
// store buffer->size in case buffer freed in KPPP_Interface->Send
|
||||||
|
status_t status = device->KPPP_Interface->Send(buffer, 0x0021); // IP_PROTOCOL 0x0021
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
device->stats.send.errors++;
|
||||||
|
dprintf("KPPP_Interface->Send(buffer, 0x0021 IP) fail\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
device->stats.send.packets++;
|
||||||
|
device->stats.send.bytes += net_buffer_size;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_receive_data(net_device *_device, net_buffer **_buffer)
|
||||||
|
{
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (device->KPPP_Interface == NULL)
|
||||||
|
return B_FILE_ERROR;
|
||||||
|
|
||||||
|
TRACE("%s: trying fifo_dequeue_buffer\n", __func__);
|
||||||
|
status_t status = sStackModule->fifo_dequeue_buffer(&(device->ppp_fifo), 0, 10000000, _buffer);
|
||||||
|
|
||||||
|
if (status < B_OK) {
|
||||||
|
TRACE("sorry! can not fifo_dequeue_buffer!\n");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (*_buffer)->interface_address = NULL; // strange need to put here
|
||||||
|
device->stats.receive.bytes += (*_buffer)->size;
|
||||||
|
device->stats.receive.packets++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_set_mtu(net_device *_device, size_t mtu)
|
||||||
|
{
|
||||||
|
ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (mtu > device->frame_size - ETHER_HEADER_LENGTH - 8
|
||||||
|
|| mtu <= ETHER_HEADER_LENGTH + 8 + 10)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
device->mtu = mtu;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_set_promiscuous(net_device *_device, bool promiscuous)
|
||||||
|
{
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_set_media(net_device *device, uint32 media)
|
||||||
|
{
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_add_multicast(struct net_device *_device, const sockaddr *_address)
|
||||||
|
{
|
||||||
|
// ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (_address->sa_family != AF_LINK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
const sockaddr_dl *address = (const sockaddr_dl *)_address;
|
||||||
|
if (address->sdl_type != IFT_ETHER)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_remove_multicast(struct net_device *_device, const sockaddr *_address)
|
||||||
|
{
|
||||||
|
// ppp_device *device = (ppp_device *)_device;
|
||||||
|
|
||||||
|
if (_address->sa_family != AF_LINK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
const sockaddr_dl *address = (const sockaddr_dl *)_address;
|
||||||
|
if (address->sdl_type != IFT_ETHER)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ppp_std_ops(int32 op, ...)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case B_MODULE_INIT:
|
||||||
|
{
|
||||||
|
status_t status = get_module(NET_STACK_MODULE_NAME,
|
||||||
|
(module_info **)&sStackModule);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = get_module(PPP_INTERFACE_MODULE_NAME,
|
||||||
|
(module_info**)&gPPPInterfaceModule);
|
||||||
|
if (status < B_OK) {
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
new (&sCheckList) DoublyLinkedList<ppp_device>;
|
||||||
|
// static C++ objects are not initialized in the module startup
|
||||||
|
|
||||||
|
sLinkCheckerThread = -1;
|
||||||
|
|
||||||
|
sLinkChangeSemaphore = create_sem(0, "ppp link change");
|
||||||
|
if (sLinkChangeSemaphore < B_OK) {
|
||||||
|
put_module(PPP_INTERFACE_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return sLinkChangeSemaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_init(&sListLock, "ppp devices");
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_MODULE_UNINIT:
|
||||||
|
{
|
||||||
|
delete_sem(sLinkChangeSemaphore);
|
||||||
|
|
||||||
|
status_t status;
|
||||||
|
wait_for_thread(sLinkCheckerThread, &status);
|
||||||
|
|
||||||
|
mutex_destroy(&sListLock);
|
||||||
|
|
||||||
|
put_module(PPP_INTERFACE_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
net_device_module_info spppModule = {
|
||||||
|
{
|
||||||
|
"network/devices/ppp/v1",
|
||||||
|
0,
|
||||||
|
ppp_std_ops
|
||||||
|
},
|
||||||
|
ppp_init,
|
||||||
|
ppp_uninit,
|
||||||
|
ppp_up,
|
||||||
|
ppp_down,
|
||||||
|
ppp_control,
|
||||||
|
ppp_send_data,
|
||||||
|
ppp_receive_data,
|
||||||
|
ppp_set_mtu,
|
||||||
|
ppp_set_promiscuous,
|
||||||
|
ppp_set_media,
|
||||||
|
ppp_add_multicast,
|
||||||
|
ppp_remove_multicast,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module_info *modules[] = {
|
||||||
|
(module_info *)&spppModule,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
|
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
|
# We need the public network headers also when not compiling for Haiku.
|
||||||
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
|
UsePrivateHeaders kernel net ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
KernelAddon ppp_frame :
|
||||||
|
ppp_frame.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||||
|
: ppp_frame ;
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Lin Longzhou, linlongzhou@163.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ethernet.h>
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <net_datalink_protocol.h>
|
||||||
|
#include <net_datalink.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <PPPControl.h>
|
||||||
|
#include <ppp_device.h>
|
||||||
|
|
||||||
|
struct ppp_frame_protocol : net_datalink_protocol {
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static net_stack_module_info *sStackModule;
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_deframe(net_device* device, net_buffer* buffer)
|
||||||
|
{
|
||||||
|
TRACE("%s: buffer type:%lx\n", __func__, buffer->type);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_init(struct net_interface* interface, net_domain* domain,
|
||||||
|
net_datalink_protocol** _protocol)
|
||||||
|
{
|
||||||
|
// We only support a single type!
|
||||||
|
dprintf("in function: %s::%s\n", __FILE__, __func__);
|
||||||
|
if (interface->device->type != IFT_PPP)
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
|
||||||
|
ppp_frame_protocol* protocol;
|
||||||
|
|
||||||
|
status_t status = sStackModule->register_device_deframer(interface->device,
|
||||||
|
&ppp_deframe);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = sStackModule->register_domain_device_handler(
|
||||||
|
interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE), domain);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = sStackModule->register_domain_device_handler(
|
||||||
|
interface->device, B_NET_FRAME_TYPE_IPV4, domain);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// Locally received buffers don't need a domain device handler, as the
|
||||||
|
// buffer reception is handled internally.
|
||||||
|
|
||||||
|
protocol = new(std::nothrow) ppp_frame_protocol;
|
||||||
|
if (protocol == NULL) {
|
||||||
|
sStackModule->unregister_device_deframer(interface->device);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_protocol = protocol;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_uninit(net_datalink_protocol* protocol)
|
||||||
|
{
|
||||||
|
sStackModule->unregister_device_deframer(protocol->interface->device);
|
||||||
|
sStackModule->unregister_device_handler(protocol->interface->device, 0);
|
||||||
|
|
||||||
|
delete protocol;
|
||||||
|
TRACE("%s\n", __func__);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_send_data(net_datalink_protocol* protocol, net_buffer* buffer)
|
||||||
|
{
|
||||||
|
TRACE("%s: next module is %s\n", __func__, protocol->next->module->info.name);
|
||||||
|
return protocol->next->module->send_data(protocol->next, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_up(net_datalink_protocol* protocol)
|
||||||
|
{
|
||||||
|
dprintf("in function: %s\n", __func__);
|
||||||
|
|
||||||
|
return protocol->next->module->interface_up(protocol->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ppp_frame_down(net_datalink_protocol* protocol)
|
||||||
|
{
|
||||||
|
dprintf("%s::%s: entry\n", __FILE__, __func__);
|
||||||
|
protocol->next->module->interface_down(protocol->next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ppp_frame_change_address(net_datalink_protocol* protocol,
|
||||||
|
net_interface_address* address, int32 option,
|
||||||
|
const struct sockaddr* oldAddress, const struct sockaddr* newAddress)
|
||||||
|
{
|
||||||
|
TRACE("in function: %s::%s\n", __FILE__, __func__);
|
||||||
|
return protocol->next->module->change_address(protocol->next, address,
|
||||||
|
option, oldAddress, newAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
PPP_module_control(int32 option, void* argument, size_t length)
|
||||||
|
{
|
||||||
|
// control_net_module_args* args=(control_net_module_args*)argument;
|
||||||
|
|
||||||
|
if (option < PPPC_CONTROL_MODULE || option > PPP_CONTROL_OPS_END)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// if (args->name != PPP_INTERFACE_MODULE_NAME)
|
||||||
|
// return B_ERROR;
|
||||||
|
|
||||||
|
switch(option)
|
||||||
|
{
|
||||||
|
case PPPC_CREATE_INTERFACE:
|
||||||
|
// process_CreateInterface(args->data, args->length);
|
||||||
|
case PPPC_CREATE_INTERFACE_WITH_NAME:
|
||||||
|
case PPPC_DELETE_INTERFACE:
|
||||||
|
case PPPC_BRING_INTERFACE_UP:
|
||||||
|
case PPPC_BRING_INTERFACE_DOWN:
|
||||||
|
case PPPC_CONTROL_INTERFACE:
|
||||||
|
case PPPC_GET_INTERFACES:
|
||||||
|
case PPPC_COUNT_INTERFACES:
|
||||||
|
case PPPC_FIND_INTERFACE_WITH_SETTINGS:
|
||||||
|
|
||||||
|
// interface control
|
||||||
|
case PPPC_GET_INTERFACE_INFO:
|
||||||
|
case PPPC_SET_USERNAME:
|
||||||
|
case PPPC_SET_PASSWORD:
|
||||||
|
case PPPC_SET_ASK_BEFORE_CONNECTING:
|
||||||
|
// ppp_up uses this in order to finalize a connection request
|
||||||
|
case PPPC_SET_MRU:
|
||||||
|
case PPPC_SET_CONNECT_ON_DEMAND:
|
||||||
|
case PPPC_SET_AUTO_RECONNECT:
|
||||||
|
case PPPC_HAS_INTERFACE_SETTINGS:
|
||||||
|
case PPPC_GET_STATISTICS:
|
||||||
|
// handler access
|
||||||
|
case PPPC_CONTROL_DEVICE:
|
||||||
|
case PPPC_CONTROL_PROTOCOL:
|
||||||
|
case PPPC_CONTROL_OPTION_HANDLER:
|
||||||
|
case PPPC_CONTROL_LCP_EXTENSION:
|
||||||
|
case PPPC_CONTROL_CHILD:
|
||||||
|
// KPPPDevice
|
||||||
|
case PPPC_GET_DEVICE_INFO:
|
||||||
|
// KPPPProtocol
|
||||||
|
case PPPC_GET_PROTOCOL_INFO:
|
||||||
|
// Common/mixed ops
|
||||||
|
case PPPC_ENABLE:
|
||||||
|
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||||
|
|
||||||
|
// these two control ops use the ppp_report_request structure
|
||||||
|
case PPPC_ENABLE_REPORTS:
|
||||||
|
case PPPC_DISABLE_REPORTS:
|
||||||
|
|
||||||
|
case PPP_CONTROL_OPS_END:
|
||||||
|
case PPPC_CONTROL_MODULE:
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ppp_frame_control(net_datalink_protocol* protocol, int32 option,
|
||||||
|
void* argument, size_t length)
|
||||||
|
{
|
||||||
|
TRACE("%s: option:%ld\n", __func__, option);
|
||||||
|
|
||||||
|
if (option >= PPPC_CONTROL_MODULE && option <=PPP_CONTROL_OPS_END)
|
||||||
|
{
|
||||||
|
status_t status =PPP_module_control(option, argument, length);
|
||||||
|
// gPPPInterfaceModule->ControlInterface(1, option, argument, length);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return protocol->next->module->control(protocol->next, option, argument,
|
||||||
|
length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ppp_frame_join_multicast(net_datalink_protocol* protocol,
|
||||||
|
const sockaddr* address)
|
||||||
|
{
|
||||||
|
TRACE("in function: %s\n", __func__);
|
||||||
|
return protocol->next->module->join_multicast(protocol->next, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ppp_frame_leave_multicast(net_datalink_protocol* protocol,
|
||||||
|
const sockaddr* address)
|
||||||
|
{
|
||||||
|
TRACE("in function: %s\n", __func__);
|
||||||
|
return protocol->next->module->leave_multicast(protocol->next, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
pppoe_frame_std_ops(int32 op, ...)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case B_MODULE_INIT:
|
||||||
|
if (get_module(NET_STACK_MODULE_NAME,
|
||||||
|
(module_info **)&sStackModule) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
case B_MODULE_UNINIT:
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static net_datalink_protocol_module_info sPPPFrameModule = {
|
||||||
|
{
|
||||||
|
"network/datalink_protocols/ppp_frame/v1",
|
||||||
|
0,
|
||||||
|
pppoe_frame_std_ops
|
||||||
|
},
|
||||||
|
ppp_frame_init,
|
||||||
|
ppp_frame_uninit,
|
||||||
|
ppp_frame_send_data,
|
||||||
|
ppp_frame_up,
|
||||||
|
ppp_frame_down,
|
||||||
|
ppp_frame_change_address,
|
||||||
|
ppp_frame_control,
|
||||||
|
ppp_frame_join_multicast,
|
||||||
|
ppp_frame_leave_multicast,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module_info* modules[] = {
|
||||||
|
(module_info*)&sPPPFrameModule,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
SubDir HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
|
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
|
# We need the public network headers also when not compiling for Haiku.
|
||||||
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
|
# UsePrivateHeaders net ;
|
||||||
|
|
||||||
|
UsePrivateHeaders kernel net ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
KernelAddon KPPPManager :
|
||||||
|
KPPPManager.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
LinkAgainst KPPPManager : libkernelppp.a ;
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||||
|
: KPPPManager ;
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2014, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, axeld@pinc-software.de
|
||||||
|
* Lin Longzhou, linlongzhou@163.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <net_stack.h>
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <ppp_device.h>
|
||||||
|
#include <KPPPManager.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct entry_private : ppp_interface_entry, DoublyLinkedListLinkImpl<entry_private> {
|
||||||
|
};
|
||||||
|
|
||||||
|
static DoublyLinkedList<entry_private> sEntryList;
|
||||||
|
|
||||||
|
net_buffer_module_info* gBufferModule = NULL;
|
||||||
|
net_stack_module_info* gStackModule = NULL;
|
||||||
|
// static struct net_interface* sinterface;
|
||||||
|
static mutex sListLock;
|
||||||
|
static uint32 ppp_interface_count;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
static KPPPInterface * GetInterface(ppp_interface_id ID);
|
||||||
|
|
||||||
|
static ppp_interface_id
|
||||||
|
CreateInterface(const driver_settings *settings, ppp_interface_id parentID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
if (parentID > 0) {
|
||||||
|
TRACE("Not support Multi_Link yet!\n");
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings == NULL) {
|
||||||
|
TRACE("No driver_settings yet!\n");
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_interface_count++;
|
||||||
|
|
||||||
|
if (GetInterface(ppp_interface_count) != NULL)
|
||||||
|
return 0l;
|
||||||
|
|
||||||
|
entry_private* pentry = new (std::nothrow) entry_private;
|
||||||
|
memset(pentry, 0, sizeof(entry_private));
|
||||||
|
pentry->accessing = ppp_interface_count;
|
||||||
|
sEntryList.Add(pentry);
|
||||||
|
|
||||||
|
KPPPInterface *device = new (std::nothrow) KPPPInterface(NULL,
|
||||||
|
pentry, ppp_interface_count, NULL, NULL);
|
||||||
|
|
||||||
|
if (device == NULL || pentry == NULL) {
|
||||||
|
TRACE("device or pentry is NULL\n");
|
||||||
|
ppp_interface_count--;
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
|
||||||
|
|
||||||
|
return ppp_interface_count; // only support 1 ppp connection right now
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ppp_interface_id
|
||||||
|
CreateInterfaceWithName(const char *name, ppp_interface_id parentID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
if (parentID > 0) {
|
||||||
|
dprintf("Not support Multi_Link yet!\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(name, "ppp", 3)) {
|
||||||
|
dprintf("%s is not ppp device!\n", name);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_interface_count++;
|
||||||
|
if (GetInterface(ppp_interface_count) != NULL) {
|
||||||
|
TRACE("PPP Interface already exist!\n");
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_private* pentry = new (std::nothrow) entry_private;
|
||||||
|
memset(pentry, 0, sizeof(entry_private));
|
||||||
|
pentry->accessing = ppp_interface_count;
|
||||||
|
sEntryList.Add(pentry);
|
||||||
|
|
||||||
|
KPPPInterface* device = new (std::nothrow) KPPPInterface(name,
|
||||||
|
pentry, ppp_interface_count, NULL, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
if (device == NULL || pentry == NULL) {
|
||||||
|
TRACE("can not create ppp interface!\n");
|
||||||
|
ppp_interface_count--;
|
||||||
|
return 0l;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
|
||||||
|
|
||||||
|
return ppp_interface_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
DeleteInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||||
|
pentry->deleting = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
RemoveInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
if (ID <= 0 || ID > ppp_interface_count)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||||
|
pentry->deleting = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static net_device *
|
||||||
|
RegisterInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
// MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
entry_private* entry = NULL;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||||
|
entry = pentry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ppp_device *device = new (std::nothrow) ppp_device;
|
||||||
|
if (device == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memset(device, 0, sizeof(ppp_device));
|
||||||
|
device->KPPP_Interface = entry->interface;
|
||||||
|
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static KPPPInterface *
|
||||||
|
GetInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
// MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
TRACE("testing interface id:%ld\n", pentry->accessing);
|
||||||
|
if ((ppp_interface_id)(pentry->accessing) == ID) {
|
||||||
|
TRACE("get interface id:%ld\n", ID);
|
||||||
|
return pentry->interface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("can not get interface id:%ld\n", ID);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
UnregisterInterface(ppp_interface_id ID)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
if (ID <= 0 || ID > ppp_interface_count)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t length)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
if (ID <= 0 || ID > ppp_interface_count)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
if ((ppp_interface_id)pentry->accessing == ID)
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32
|
||||||
|
GetInterfaces(ppp_interface_id *interfaces, int32 count, ppp_interface_filter filter)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock);
|
||||||
|
|
||||||
|
if (count <= 0 || count > (int32)ppp_interface_count)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
uint32 ppp_count = 0;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
entry_private* pentry = iterator.Next();
|
||||||
|
interfaces[ppp_count] = pentry->accessing;
|
||||||
|
ppp_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ppp_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int32
|
||||||
|
CountInterfaces(ppp_interface_filter filter)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
uint32 ppp_count = 0;
|
||||||
|
|
||||||
|
DoublyLinkedList<entry_private>::Iterator iterator
|
||||||
|
= sEntryList.GetIterator();
|
||||||
|
while (iterator.HasNext()) {
|
||||||
|
iterator.Next();
|
||||||
|
ppp_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ppp_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
EnableReports(ppp_report_type type, thread_id thread, int32 flags)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
return; // need more portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DisableReports(ppp_report_type type, thread_id thread)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
return; // need more portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
DoesReport(ppp_report_type type, thread_id thread)
|
||||||
|
{
|
||||||
|
MutexLocker _(sListLock); // auto_lock
|
||||||
|
|
||||||
|
return false; // need more portrait
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
KPPPManager_std_ops(int32 op, ...)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case B_MODULE_INIT:
|
||||||
|
mutex_init(&sListLock, "KPPPManager");
|
||||||
|
new (&sEntryList) DoublyLinkedList<entry_private>;
|
||||||
|
// static C++ objects are not initialized in the module startup
|
||||||
|
ppp_interface_count = 0;
|
||||||
|
|
||||||
|
if (get_module(NET_STACK_MODULE_NAME, (module_info**)&gStackModule)
|
||||||
|
!= B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule)
|
||||||
|
!= B_OK) {
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
case B_MODULE_UNINIT:
|
||||||
|
mutex_destroy(&sListLock);
|
||||||
|
|
||||||
|
put_module(NET_BUFFER_MODULE_NAME);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ppp_interface_module_info sKPPPManagerModule = {
|
||||||
|
{
|
||||||
|
PPP_INTERFACE_MODULE_NAME,
|
||||||
|
0,
|
||||||
|
KPPPManager_std_ops
|
||||||
|
},
|
||||||
|
CreateInterface,
|
||||||
|
CreateInterfaceWithName,
|
||||||
|
DeleteInterface,
|
||||||
|
RemoveInterface,
|
||||||
|
RegisterInterface,
|
||||||
|
GetInterface,
|
||||||
|
UnregisterInterface,
|
||||||
|
ControlInterface,
|
||||||
|
GetInterfaces,
|
||||||
|
CountInterfaces,
|
||||||
|
EnableReports,
|
||||||
|
DisableReports,
|
||||||
|
DoesReport
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module_info* modules[] = {
|
||||||
|
(module_info*)&sKPPPManagerModule,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
@@ -3,11 +3,12 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* 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");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
pppoe_header *header ;
|
||||||
|
status_t status = gBufferModule->append_size(packet, 1492, (void **)&header);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf("append size failure\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
header->version = PPPoE_VERSION;
|
header->version = PPPoE_VERSION;
|
||||||
header->type = PPPoE_TYPE;
|
header->type = PPPoE_TYPE;
|
||||||
@@ -137,7 +154,7 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
|||||||
|
|
||||||
// make sure we have enough space left
|
// make sure we have enough space left
|
||||||
if(MTU - length < tag->length) {
|
if(MTU - length < tag->length) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +167,11 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
|||||||
}
|
}
|
||||||
|
|
||||||
header->length = htons(length);
|
header->length = htons(length);
|
||||||
packet->m_pkthdr.len = packet->m_len = length + PPPoE_HEADER_SIZE;
|
status = gBufferModule->trim(packet, length + PPPoE_HEADER_SIZE);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf("trim buffer failure\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <TemplateList.h>
|
#include <TemplateList.h>
|
||||||
|
|
||||||
|
#define ETHER_HDR_LEN 14
|
||||||
|
|
||||||
enum PPPoE_TAG_TYPE {
|
enum PPPoE_TAG_TYPE {
|
||||||
END_OF_LIST = 0x0000,
|
END_OF_LIST = 0x0000,
|
||||||
@@ -37,13 +38,13 @@ typedef struct pppoe_tag {
|
|||||||
uint16 type;
|
uint16 type;
|
||||||
uint16 length;
|
uint16 length;
|
||||||
uint8 data[0];
|
uint8 data[0];
|
||||||
};
|
} pppoe_tag;
|
||||||
|
|
||||||
|
|
||||||
class DiscoveryPacket {
|
class DiscoveryPacket {
|
||||||
public:
|
public:
|
||||||
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
|
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
|
||||||
DiscoveryPacket(struct mbuf *packet, uint32 start = 0);
|
DiscoveryPacket(net_buffer *packet, uint32 start = 0);
|
||||||
~DiscoveryPacket();
|
~DiscoveryPacket();
|
||||||
|
|
||||||
status_t InitCheck() const
|
status_t InitCheck() const
|
||||||
@@ -66,8 +67,8 @@ class DiscoveryPacket {
|
|||||||
pppoe_tag *TagAt(int32 index) const;
|
pppoe_tag *TagAt(int32 index) const;
|
||||||
pppoe_tag *TagWithType(uint16 type) const;
|
pppoe_tag *TagWithType(uint16 type) const;
|
||||||
|
|
||||||
struct mbuf *ToMbuf(uint32 MTU, uint32 reserve = ETHER_HDR_LEN);
|
net_buffer *ToNetBuffer(uint32 MTU);
|
||||||
// the user is responsible for freeing the mbuf
|
// the user is responsible for freeing the net_buffer
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 fCode;
|
uint8 fCode;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
SubDir HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
SubDirC++Flags -fno-rtti ;
|
||||||
|
|
||||||
if $(TARGET_PLATFORM) != haiku {
|
if $(TARGET_PLATFORM) != haiku {
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||||
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
# for kernel_cpp.h and BLocker
|
UsePrivateKernelHeaders ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
UsePrivateHeaders [ FDirName kernel ] ;
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
libkernelppp headers ] : true ;
|
libkernelppp headers ] : true ;
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
SubDirC++Flags -fno-rtti ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
KernelAddon pppoe :
|
KernelAddon pppoe :
|
||||||
pppoe.cpp
|
pppoe.cpp
|
||||||
PPPoEDevice.cpp
|
PPPoEDevice.cpp
|
||||||
@@ -32,5 +26,5 @@ LinkAgainst pppoe : libkernelppp.a ;
|
|||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
HaikuInstall install-networking
|
HaikuInstall install-networking
|
||||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
: /boot/home/config/add-ons/kernel/haiku/ppp
|
||||||
: pppoe ;
|
: pppoe ;
|
||||||
|
|||||||
@@ -8,10 +8,15 @@
|
|||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/if_ether.h>
|
|
||||||
|
#include <ethernet.h>
|
||||||
|
#include <ether_driver.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
class PPPoEDevice;
|
class PPPoEDevice;
|
||||||
|
|
||||||
|
#define B_NET_FRAME_TYPE_PPPOE B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE)
|
||||||
|
#define B_NET_FRAME_TYPE_PPPOE_DISCOVERY B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE_DISCOVERY)
|
||||||
|
|
||||||
#define PPPoE_QUERY_REPORT_SIZE 2048
|
#define PPPoE_QUERY_REPORT_SIZE 2048
|
||||||
#define PPPoE_QUERY_REPORT 'PoEQ'
|
#define PPPoE_QUERY_REPORT 'PoEQ'
|
||||||
@@ -60,14 +65,14 @@ typedef struct complete_pppoe_header {
|
|||||||
|
|
||||||
|
|
||||||
// defined in pppoe.cpp
|
// defined in pppoe.cpp
|
||||||
extern ifnet *FindPPPoEInterface(const char *name);
|
extern net_device *FindPPPoEInterface(const char *name);
|
||||||
extern uint32 NewHostUniq();
|
extern uint32 NewHostUniq();
|
||||||
extern void add_device(PPPoEDevice *device);
|
extern void add_device(PPPoEDevice *device);
|
||||||
extern void remove_device(PPPoEDevice *device);
|
extern void remove_device(PPPoEDevice *device);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// defined in PPPoEDevice.cpp
|
// defined in PPPoEDevice.cpp
|
||||||
extern void dump_packet(struct mbuf *packet);
|
extern void dump_packet(net_buffer *packet);
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,25 +3,39 @@
|
|||||||
* 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;
|
||||||
|
|
||||||
@@ -38,6 +52,8 @@ dump_packet(struct mbuf *packet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -62,22 +78,31 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
|
|||||||
// 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);
|
||||||
fServiceName = get_parameter_value(PPPoE_SERVICE_NAME_KEY, settings);
|
TRACE("fACName is %s\n", fACName ? fACName : "NULL");
|
||||||
|
|
||||||
fEthernetIfnet = FindPPPoEInterface(interfaceName);
|
fServiceName = get_parameter_value(PPPoE_SERVICE_NAME_KEY, settings);
|
||||||
|
TRACE("fServiceName is %s\n", fServiceName ? fServiceName : "NULL");
|
||||||
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -101,6 +128,24 @@ PPPoEDevice::Up()
|
|||||||
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;
|
||||||
@@ -125,19 +170,21 @@ PPPoEDevice::Up()
|
|||||||
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();
|
||||||
|
|
||||||
|
memset(header.destination, 0xff, ETHER_ADDRESS_LENGTH);
|
||||||
|
memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||||
|
header.type = htons(ETHER_TYPE_PPPOE_DISCOVERY);
|
||||||
|
ethernetHeader.Sync();
|
||||||
// raw packet with ethernet header
|
// raw packet with ethernet header
|
||||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
|
||||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
|
||||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
|
||||||
|
|
||||||
// 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()) {
|
||||||
@@ -151,13 +198,24 @@ PPPoEDevice::Up()
|
|||||||
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;
|
||||||
@@ -169,6 +227,11 @@ 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)
|
||||||
@@ -191,9 +254,9 @@ PPPoEDevice::Down()
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@@ -205,13 +268,13 @@ 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,7 +305,7 @@ 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.
|
||||||
|
|
||||||
@@ -252,41 +315,46 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
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();
|
||||||
|
header.length = htons(length);
|
||||||
|
bufferheader.Sync();
|
||||||
|
|
||||||
// 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();
|
||||||
|
|
||||||
|
memcpy(ethheader.destination, fPeer, ETHER_ADDRESS_LENGTH);
|
||||||
|
memcpy(ethheader.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||||
|
ethheader.type = htons(ETHER_TYPE_PPPOE);
|
||||||
|
ethernetHeader.Sync();
|
||||||
// raw packet with ethernet header
|
// raw packet with ethernet header
|
||||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
|
||||||
ethernetHeader->ether_type = ETHERTYPE_PPPOE;
|
|
||||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
|
||||||
|
|
||||||
if(!packet || !mtod(packet, pppoe_header*))
|
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();
|
||||||
@@ -299,57 +367,83 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
PPPoEDevice::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
|
TRACE("%s entering %s: protocolNumber:%x\n", __FILE__, __func__, protocolNumber);
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
else if(InitCheck() != B_OK || IsDown()) {
|
|
||||||
m_freem(packet);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
complete_pppoe_header *completeHeader = mtod(packet, complete_pppoe_header*);
|
if (InitCheck() != B_OK || IsDown()) {
|
||||||
if(!completeHeader) {
|
dprintf("PPPoED InitCheck fail or IsDown\n");
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive fail\n");
|
||||||
return B_ERROR;
|
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
|
if (PPP_Packet_Type == B_NET_FRAME_TYPE_PPPOE) {
|
||||||
|| header->code != 0x0 || header->sessionID != SessionID()) {
|
TRACE("ETHER_TYPE_PPPOE\n");
|
||||||
m_freem(packet);
|
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK) {
|
||||||
|
TRACE("creat NetBufferHeaderReader fail\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
pppoe_header &header = bufferheader.Data();
|
||||||
|
uint16 ppppoe_payload = ntohs(header.length);
|
||||||
|
|
||||||
|
if (!IsUp() || header.version != PPPoE_VERSION || header.type != PPPoE_TYPE
|
||||||
|
|| header.code != 0x0 || header.sessionID != SessionID()) {
|
||||||
|
// gBufferModule->free(packet);
|
||||||
|
TRACE("basic pppoe header check fail\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_adj(packet, PPPoE_HEADER_SIZE);
|
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: {
|
||||||
|
dprintf("processing PADO\n");
|
||||||
if (fState != PADI_SENT) {
|
if (fState != PADI_SENT) {
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
|
dprintf("PPPoEDevice::Receive faile not PADI_Sent \n");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,9 +458,9 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
@@ -374,9 +468,9 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -390,7 +484,8 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
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;
|
||||||
|
|
||||||
@@ -400,59 +495,68 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
|
memcpy(header.destination, fPeer, ETHER_ADDRESS_LENGTH);
|
||||||
|
memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||||
|
header.type=htons(ETHER_TYPE_PPPOE_DISCOVERY);
|
||||||
|
ethernetHeader.Sync();
|
||||||
// raw packet with ethernet header
|
// raw packet with ethernet header
|
||||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
|
||||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
|
||||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
|
||||||
|
|
||||||
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:
|
||||||
|
dprintf("procesing PADS\n");
|
||||||
if (fState != PADR_SENT
|
if (fState != PADR_SENT
|
||||||
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
|
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
|
||||||
m_freem(packet);
|
// 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:
|
||||||
|
dprintf("procesing PADT\n");
|
||||||
if (!IsUp()
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,14 +569,15 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
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;
|
|
||||||
|
|
||||||
m_freem(packet);
|
dprintf("PPPoEDevice::Receive PADX fine!\n");
|
||||||
return result;
|
// gBufferModule->free(packet);
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -480,7 +585,6 @@ 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;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
|
|
||||||
#include <KPPPDevice.h>
|
#include <KPPPDevice.h>
|
||||||
|
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
|
||||||
|
|
||||||
enum pppoe_state {
|
enum pppoe_state {
|
||||||
INITIAL,
|
INITIAL,
|
||||||
@@ -25,7 +28,7 @@ class PPPoEDevice : public KPPPDevice {
|
|||||||
public:
|
public:
|
||||||
PPPoEDevice(KPPPInterface& interface, driver_parameter *settings);
|
PPPoEDevice(KPPPInterface& interface, driver_parameter *settings);
|
||||||
|
|
||||||
ifnet *EthernetIfnet() const
|
net_device *EthernetIfnet() const
|
||||||
{ return fEthernetIfnet; }
|
{ return fEthernetIfnet; }
|
||||||
|
|
||||||
const uint8 *Peer() const
|
const uint8 *Peer() const
|
||||||
@@ -50,17 +53,19 @@ class PPPoEDevice : public KPPPDevice {
|
|||||||
|
|
||||||
virtual uint32 CountOutputBytes() const;
|
virtual uint32 CountOutputBytes() const;
|
||||||
|
|
||||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber = 0);
|
virtual status_t Send(net_buffer *packet, uint16 protocolNumber = 0);
|
||||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber = 0);
|
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber = 0);
|
||||||
|
|
||||||
virtual void Pulse();
|
virtual void Pulse();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ifnet *fEthernetIfnet;
|
net_device *fEthernetIfnet;
|
||||||
uint8 fPeer[6];
|
uint8 fPeer[6];
|
||||||
|
uint8 fEtherAddr[6];
|
||||||
uint16 fSessionID;
|
uint16 fSessionID;
|
||||||
uint32 fHostUniq;
|
uint32 fHostUniq;
|
||||||
const char *fACName, *fServiceName;
|
const char *fACName, *fServiceName;
|
||||||
|
const char *finterfaceName;
|
||||||
|
|
||||||
uint32 fAttempts;
|
uint32 fAttempts;
|
||||||
bigtime_t fNextTimeout;
|
bigtime_t fNextTimeout;
|
||||||
|
|||||||
@@ -5,34 +5,46 @@
|
|||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
#include <net_module.h>
|
|
||||||
|
|
||||||
#include <ethernet_module.h>
|
#include <lock.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
|
||||||
|
#include <net/if_types.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_datalink.h> // for get_interface and control
|
||||||
|
#include <net_stack.h>
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
|
||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
#include <KPPPModule.h>
|
#include <KPPPModule.h>
|
||||||
#include <KPPPUtils.h>
|
#include <KPPPUtils.h>
|
||||||
#include <LockerHelper.h>
|
|
||||||
|
|
||||||
#include "PPPoEDevice.h"
|
#include "PPPoEDevice.h"
|
||||||
#include "DiscoveryPacket.h"
|
#include "DiscoveryPacket.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct pppoe_query {
|
typedef struct pppoe_query {
|
||||||
ifnet *ethernetIfnet;
|
net_device *ethernetIfnet;
|
||||||
uint32 hostUniq;
|
uint32 hostUniq;
|
||||||
thread_id receiver;
|
thread_id receiver;
|
||||||
} pppoe_query;
|
} pppoe_query;
|
||||||
|
|
||||||
#define PPPoE_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pppoe"
|
#define PPPoE_MODULE_NAME "network/ppp/pppoe"
|
||||||
|
|
||||||
|
net_stack_module_info *gStackModule = NULL;
|
||||||
|
net_buffer_module_info *gBufferModule = NULL;
|
||||||
|
net_datalink_module_info *sDatalinkModule = NULL;
|
||||||
|
|
||||||
struct core_module_info *core = NULL;
|
|
||||||
static struct ethernet_module_info *sEthernet;
|
|
||||||
static int32 sHostUniq = 0;
|
static int32 sHostUniq = 0;
|
||||||
status_t std_ops(int32 op, ...);
|
status_t std_ops(int32 op, ...);
|
||||||
|
|
||||||
static BLocker sLock("PPPoEList");
|
// static mutex sLock("PPPoEList");
|
||||||
|
|
||||||
static TemplateList<PPPoEDevice*> *sDevices;
|
static TemplateList<PPPoEDevice*> *sDevices;
|
||||||
static TemplateList<pppoe_query*> *sQueries;
|
static TemplateList<pppoe_query*> *sQueries;
|
||||||
|
|
||||||
@@ -76,19 +88,43 @@ SendQueryPacket(pppoe_query *query, DiscoveryPacket& discovery)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
return NULL;
|
||||||
|
|
||||||
ifnet *current = get_interfaces();
|
net_interface* ethernetInterfaceOfPPPOE = NULL;
|
||||||
for(; current; current = current->if_next) {
|
net_domain* domain = NULL;
|
||||||
if(current->if_type == IFT_ETHER && current->if_name
|
|
||||||
&& !strcmp(current->if_name, name))
|
domain = gStackModule->get_domain(AF_INET);
|
||||||
return current;
|
ethernetInterfaceOfPPPOE = get_interface_by_name(domain, name);
|
||||||
|
|
||||||
|
if (ethernetInterfaceOfPPPOE == NULL) {
|
||||||
|
TRACE("get_interface_by_name can not find eth\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ethernetInterfaceOfPPPOE->device)
|
||||||
|
return ethernetInterfaceOfPPPOE->device;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +141,7 @@ 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);
|
||||||
}
|
}
|
||||||
@@ -116,84 +152,124 @@ 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;
|
||||||
|
|
||||||
|
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||||
|
if (bufferheader.Status() != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
pppoe_header &header = bufferheader.Data();
|
||||||
|
|
||||||
|
// remove the following lines when pppoe server is enabled
|
||||||
|
if (header.code == PADI) {
|
||||||
|
TRACE("PADI packet received, ignoreing!\n");
|
||||||
|
gBufferModule->free(packet);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.code == PADO || header.code == PADR || header.code == PADS || header.code == PADT)
|
||||||
|
{
|
||||||
|
uint8 peerEtherAddr[ETHER_ADDRESS_LENGTH];
|
||||||
|
struct sockaddr_dl& source = *(struct sockaddr_dl*)packet->source;
|
||||||
|
memcpy(peerEtherAddr, source.sdl_data, ETHER_ADDRESS_LENGTH);
|
||||||
|
const char *str = header.code == PADI ? "PADI" :
|
||||||
|
header.code == PADO ? "PADO" :
|
||||||
|
header.code == PADR ? "PADR" :
|
||||||
|
header.code == PADS ? "PADS" :
|
||||||
|
"PADT" ;
|
||||||
|
|
||||||
|
dprintf("%s from:%02x:%02x:%02x:%02x:%02x:%02x code:%02x\n", str,
|
||||||
|
peerEtherAddr[0], peerEtherAddr[1], peerEtherAddr[2],
|
||||||
|
peerEtherAddr[3], peerEtherAddr[4], peerEtherAddr[5],
|
||||||
|
header.code);
|
||||||
|
}
|
||||||
|
|
||||||
ifnet *sourceIfnet = packet->m_pkthdr.rcvif;
|
|
||||||
complete_pppoe_header *header = mtod(packet, complete_pppoe_header*);
|
|
||||||
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,
|
||||||
|
ntohs(linkAddress.sdl_e_type));
|
||||||
|
|
||||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC
|
// MutexLocker locker(sLock);
|
||||||
&& header->pppoeHeader.length <= PPPoE_QUERY_REPORT_SIZE) {
|
|
||||||
|
if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
|
||||||
|
&& ntohs(header.length) <= PPPoE_QUERY_REPORT_SIZE) {
|
||||||
for (int32 index = 0; index < sDevices->CountItems(); index++) {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("in pppoed processing sDevices->CountItems(): %ld\n", sDevices->CountItems());
|
||||||
|
|
||||||
for (int32 index = 0; index < sDevices->CountItems(); index++) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -231,14 +307,14 @@ control(uint32 op, void *data, size_t length)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@@ -263,16 +339,19 @@ control(uint32 op, void *data, size_t length)
|
|||||||
query.hostUniq = NewHostUniq();
|
query.hostUniq = NewHostUniq();
|
||||||
query.receiver = request->receiver;
|
query.receiver = request->receiver;
|
||||||
|
|
||||||
sLock.Lock();
|
{
|
||||||
|
// MutexLocker tlocker(sLock);
|
||||||
|
TRACE("add query\n");
|
||||||
sQueries->AddItem(&query);
|
sQueries->AddItem(&query);
|
||||||
sLock.Unlock();
|
}
|
||||||
|
|
||||||
snooze(2000000);
|
snooze(2000000);
|
||||||
// wait two seconds for results
|
// wait two seconds for results
|
||||||
|
{
|
||||||
sLock.Lock();
|
// MutexLocker tlocker(sLock);
|
||||||
|
TRACE("remove query\n");
|
||||||
sQueries->RemoveItem(&query);
|
sQueries->RemoveItem(&query);
|
||||||
sLock.Unlock();
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -300,30 +379,38 @@ 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);
|
||||||
|
put_module(NET_STACK_MODULE_NAME);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -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) ] ;
|
||||||
|
|||||||
@@ -9,11 +9,13 @@
|
|||||||
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.
|
||||||
|
|
||||||
@@ -27,18 +29,21 @@ 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)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &header = bufferhead.Data();
|
||||||
|
|
||||||
SetID(header->id);
|
SetID(header.id);
|
||||||
if (!SetCode(header->code))
|
if (!SetCode(header.code))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint16 length = ntohs(header->length);
|
uint16 length = ntohs(header.length);
|
||||||
|
|
||||||
if (length < 6 || length > packet->m_len)
|
if (length < 6 || length > packet->size)
|
||||||
return;
|
return;
|
||||||
// there are no items (or one corrupted item)
|
// there are no items (or one corrupted item)
|
||||||
|
|
||||||
@@ -46,7 +51,7 @@ KPPPConfigurePacket::KPPPConfigurePacket(struct mbuf *packet)
|
|||||||
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
|
||||||
@@ -157,22 +162,31 @@ KPPPConfigurePacket::ItemWithType(uint8 type) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \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__);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
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();
|
||||||
@@ -185,7 +199,7 @@ KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve)
|
|||||||
|
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +209,13 @@ KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve)
|
|||||||
|
|
||||||
length += 4;
|
length += 4;
|
||||||
header->length = htons(length);
|
header->length = htons(length);
|
||||||
packet->m_pkthdr.len = packet->m_len = length;
|
|
||||||
|
|
||||||
return packet;
|
status = gBufferModule->trim(buffer, length);
|
||||||
|
if (status < B_OK) {
|
||||||
|
dprintf("%s::%s: gBufferModule->trim\n", __FILE__, __func__);
|
||||||
|
gBufferModule->free(buffer);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
#include <KPPPDevice.h>
|
#include <KPPPDevice.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
|
|
||||||
#include <PPPControl.h>
|
#include <PPPControl.h>
|
||||||
|
|
||||||
@@ -52,6 +51,7 @@ KPPPDevice::~KPPPDevice()
|
|||||||
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)
|
||||||
|
|||||||
@@ -23,7 +23,11 @@
|
|||||||
// void (KernelExport.h) and once with int (stdio.h).
|
// void (KernelExport.h) and once with int (stdio.h).
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <core_funcs.h>
|
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <net_stack.h>
|
||||||
|
#include <ppp_device.h>
|
||||||
|
|
||||||
// now our headers...
|
// now our headers...
|
||||||
#include <KPPPInterface.h>
|
#include <KPPPInterface.h>
|
||||||
@@ -38,7 +42,8 @@
|
|||||||
#include <KPPPUtils.h>
|
#include <KPPPUtils.h>
|
||||||
|
|
||||||
// general helper classes not only belonging to us
|
// general helper classes not only belonging to us
|
||||||
#include <LockerHelper.h>
|
// #include <lock.h>
|
||||||
|
// #include <util/AutoLock.h>
|
||||||
|
|
||||||
// tools only for us :)
|
// tools only for us :)
|
||||||
#include "settings_tools.h"
|
#include "settings_tools.h"
|
||||||
@@ -62,6 +67,9 @@ typedef struct reconnect_info {
|
|||||||
uint32 delay;
|
uint32 delay;
|
||||||
} reconnect_info;
|
} reconnect_info;
|
||||||
|
|
||||||
|
extern net_buffer_module_info *gBufferModule;
|
||||||
|
extern net_stack_module_info *gStackModule;
|
||||||
|
|
||||||
status_t reconnect_thread(void *data);
|
status_t reconnect_thread(void *data);
|
||||||
|
|
||||||
// other functions
|
// other functions
|
||||||
@@ -95,7 +103,7 @@ KPPPInterface::KPPPInterface(const char *name, ppp_interface_entry *entry,
|
|||||||
fParent(NULL),
|
fParent(NULL),
|
||||||
fIsMultilink(false),
|
fIsMultilink(false),
|
||||||
fAutoReconnect(false),
|
fAutoReconnect(false),
|
||||||
fConnectOnDemand(false),
|
fConnectOnDemand(true),
|
||||||
fAskBeforeConnecting(false),
|
fAskBeforeConnecting(false),
|
||||||
fMode(PPP_CLIENT_MODE),
|
fMode(PPP_CLIENT_MODE),
|
||||||
fLocalPFCState(PPP_PFC_DISABLED),
|
fLocalPFCState(PPP_PFC_DISABLED),
|
||||||
@@ -250,10 +258,11 @@ KPPPInterface::~KPPPInterface()
|
|||||||
// This lock is not released until we are actually deleted.
|
// This lock is not released until we are actually deleted.
|
||||||
while (true) {
|
while (true) {
|
||||||
Down();
|
Down();
|
||||||
fLock.Lock();
|
{
|
||||||
|
MutexLocker (fLock);
|
||||||
if (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)
|
if (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)
|
||||||
break;
|
break;
|
||||||
fLock.Unlock();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Report(PPP_DESTRUCTION_REPORT, 0, &fID, sizeof(ppp_interface_id));
|
Report(PPP_DESTRUCTION_REPORT, 0, &fID, sizeof(ppp_interface_id));
|
||||||
@@ -296,7 +305,9 @@ KPPPInterface::~KPPPInterface()
|
|||||||
void
|
void
|
||||||
KPPPInterface::Delete()
|
KPPPInterface::Delete()
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
// MutexLocker locker(fLock);
|
||||||
|
// alreay locked in KPPPStatemachine::DownEvent
|
||||||
|
// uncomment this line will cause double lock
|
||||||
|
|
||||||
if (fDeleteCounter > 0)
|
if (fDeleteCounter > 0)
|
||||||
return;
|
return;
|
||||||
@@ -364,7 +375,9 @@ KPPPInterface::SetMRU(uint32 MRU)
|
|||||||
if (Device() && MRU > Device()->MTU() - 2)
|
if (Device() && MRU > Device()->MTU() - 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
// MutexLocker locker(fLock);
|
||||||
|
// uncomment this line will cause double lock
|
||||||
|
// alreay locked in ::Up and ::KPPPInterface
|
||||||
|
|
||||||
fMRU = MRU;
|
fMRU = MRU;
|
||||||
|
|
||||||
@@ -406,7 +419,298 @@ KPPPInterface::PacketOverhead() const
|
|||||||
status_t
|
status_t
|
||||||
KPPPInterface::Control(uint32 op, void *data, size_t length)
|
KPPPInterface::Control(uint32 op, void *data, size_t length)
|
||||||
{
|
{
|
||||||
switch (op) {
|
TRACE("%s:%s\n", __FILE__, __func__);
|
||||||
|
|
||||||
|
control_net_module_args* args = (control_net_module_args*)data;
|
||||||
|
if (op != NET_STACK_CONTROL_NET_MODULE) {
|
||||||
|
dprintf("unknow op!!\n");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args->op) {
|
||||||
|
case PPPC_COUNT_INTERFACES:
|
||||||
|
{
|
||||||
|
// should be implepented
|
||||||
|
dprintf("PPPC_COUNT_INTERFACES should be implepentd\n");
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_GET_INTERFACES:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_GET_INTERFACES\n");
|
||||||
|
ppp_get_interfaces_info* info = (ppp_get_interfaces_info*)args->data;
|
||||||
|
dprintf("info->interfaces: %p\n", info->interfaces);
|
||||||
|
*(info->interfaces) = 1;
|
||||||
|
info->resultCount = 1;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_CONTROL_INTERFACE:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_CONTROL_INTERFACE\n");
|
||||||
|
ppp_control_info* control = (ppp_control_info*)args->data;
|
||||||
|
|
||||||
|
switch (control->op) {
|
||||||
|
case PPPC_GET_INTERFACE_INFO:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_GET_INTERFACE_INFO\n");
|
||||||
|
if (control->length < sizeof(ppp_interface_info_t) || !control->data) {
|
||||||
|
dprintf("size wrong!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppp_interface_info *info = (ppp_interface_info*) control->data;
|
||||||
|
dprintf("info addr:%p\n", info);
|
||||||
|
memset(info, 0, sizeof(ppp_interface_info_t));
|
||||||
|
if (Name())
|
||||||
|
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||||
|
|
||||||
|
if (Ifnet())
|
||||||
|
info->if_unit = Ifnet()->index;
|
||||||
|
else
|
||||||
|
info->if_unit = -1;
|
||||||
|
info->mode = Mode();
|
||||||
|
info->state = State();
|
||||||
|
info->phase = Phase();
|
||||||
|
info->localAuthenticationStatus =
|
||||||
|
StateMachine().LocalAuthenticationStatus();
|
||||||
|
info->peerAuthenticationStatus =
|
||||||
|
StateMachine().PeerAuthenticationStatus();
|
||||||
|
info->localPFCState = LocalPFCState();
|
||||||
|
info->peerPFCState = PeerPFCState();
|
||||||
|
info->pfcOptions = PFCOptions();
|
||||||
|
info->protocolsCount = CountProtocols();
|
||||||
|
info->optionHandlersCount = LCP().CountOptionHandlers();
|
||||||
|
info->LCPExtensionsCount = 0;
|
||||||
|
info->childrenCount = CountChildren();
|
||||||
|
info->MRU = MRU();
|
||||||
|
info->interfaceMTU = InterfaceMTU();
|
||||||
|
info->connectAttempt = fConnectAttempt;
|
||||||
|
info->connectRetriesLimit = fConnectRetriesLimit;
|
||||||
|
info->connectRetryDelay = ConnectRetryDelay();
|
||||||
|
info->reconnectDelay = ReconnectDelay();
|
||||||
|
info->connectedSince = ConnectedSince();
|
||||||
|
info->idleSince = IdleSince();
|
||||||
|
info->disconnectAfterIdleSince = DisconnectAfterIdleSince();
|
||||||
|
info->doesConnectOnDemand = DoesConnectOnDemand();
|
||||||
|
info->doesAutoReconnect = DoesAutoReconnect();
|
||||||
|
info->hasDevice = Device();
|
||||||
|
info->isMultilink = IsMultilink();
|
||||||
|
info->hasParent = Parent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_SET_USERNAME:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_SET_USERNAME\n");
|
||||||
|
if (control->length > PPP_HANDLER_NAME_LENGTH_LIMIT || !control->data) {
|
||||||
|
dprintf("size wrong!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexLocker locker(fLock);
|
||||||
|
// login information can only be changed before we authenticate
|
||||||
|
if (Phase() >= PPP_AUTHENTICATION_PHASE)
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
|
free(fUsername);
|
||||||
|
fUsername = control->data ? strdup((const char*) control->data) : strdup("");
|
||||||
|
dprintf("set ppp user name to %s\n", fUsername);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_SET_PASSWORD:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_SET_PASSWORD\n");
|
||||||
|
if (control->length > PPP_HANDLER_NAME_LENGTH_LIMIT || !control->data) {
|
||||||
|
dprintf("size wrong!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexLocker locker(fLock);
|
||||||
|
// login information can only be changed before we authenticate
|
||||||
|
if (Phase() >= PPP_AUTHENTICATION_PHASE)
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
|
free(fPassword);
|
||||||
|
fPassword = control->data ? strdup((const char*) control->data) : strdup("");
|
||||||
|
dprintf("set ppp password to %s!\n", fPassword);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_SET_ASK_BEFORE_CONNECTING:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_SET_ASK_BEFORE_CONNECTING\n");
|
||||||
|
if (control->length < sizeof(uint32) || !control->data) {
|
||||||
|
dprintf("size wrong!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAskBeforeConnecting(*((uint32*)control->data));
|
||||||
|
dprintf("goto PPPC_SET_ASK_BEFORE_CONNECTING here!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_GET_STATISTICS:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_GET_STATISTICS\n");
|
||||||
|
if (control->length < sizeof(ppp_statistics) || !control->data) {
|
||||||
|
dprintf("size wrong!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("should PPPC_GET_STATISTICS here!\n");
|
||||||
|
|
||||||
|
memcpy(control->data, &fStatistics, sizeof(ppp_statistics));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_HAS_INTERFACE_SETTINGS:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_HAS_INTERFACE_SETTINGS\n");
|
||||||
|
if (control->length < sizeof(driver_settings) || !control->data) {
|
||||||
|
dprintf("size wrong!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("should PPPC_HAS_INTERFACE_SETTINGS here!\n");
|
||||||
|
|
||||||
|
if (equal_interface_settings(Settings(), (driver_settings*)control->data))
|
||||||
|
return B_OK;
|
||||||
|
else
|
||||||
|
return B_ERROR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_ENABLE_REPORTS:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_ENABLE_REPORTS\n");
|
||||||
|
if (control->length < sizeof(ppp_report_request) || !control->data) {
|
||||||
|
dprintf("size wrong!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("should PPPC_ENABLE_REPORTS here!\n");
|
||||||
|
|
||||||
|
MutexLocker locker(fLock);
|
||||||
|
ppp_report_request *request = (ppp_report_request*) control->data;
|
||||||
|
// first, we send an initial state report
|
||||||
|
if (request->type == PPP_CONNECTION_REPORT) {
|
||||||
|
ppp_report_packet report;
|
||||||
|
report.type = PPP_CONNECTION_REPORT;
|
||||||
|
report.code = StateMachine().fLastConnectionReportCode;
|
||||||
|
report.length = sizeof(fID);
|
||||||
|
KPPPReportManager::SendReport(request->thread, &report);
|
||||||
|
if (request->flags & PPP_REMOVE_AFTER_REPORT)
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
ReportManager().EnableReports(request->type, request->thread,
|
||||||
|
request->flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_DISABLE_REPORTS:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_DISABLE_REPORTS\n");
|
||||||
|
if (control->length < sizeof(ppp_report_request) || !control->data) {
|
||||||
|
dprintf("size wrong!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("should PPPC_DISABLE_REPORTS here!\n");
|
||||||
|
|
||||||
|
ppp_report_request *request = (ppp_report_request*) control->data;
|
||||||
|
ReportManager().DisableReports(request->type, request->thread);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_CONTROL_DEVICE:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_CONTROL_DEVICE\n");
|
||||||
|
if (control->length < sizeof(ppp_control_info) || !control->data)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
ppp_control_info *controlInfo = (ppp_control_info*) control->data;
|
||||||
|
if (controlInfo->index != 0 || !Device())
|
||||||
|
{
|
||||||
|
dprintf("index is 0 or no Device\n");
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Device()->Control(controlInfo->op, controlInfo->data, controlInfo->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_CONTROL_PROTOCOL:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_CONTROL_PROTOCOL\n");
|
||||||
|
if (control->length < sizeof(ppp_control_info) || !control->data)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
ppp_control_info *controlInfo = (ppp_control_info*) control->data;
|
||||||
|
KPPPProtocol *protocol = ProtocolAt(controlInfo->index);
|
||||||
|
if (!protocol)
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
|
return protocol->Control(controlInfo->op, controlInfo->data, controlInfo->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_CONTROL_OPTION_HANDLER:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_CONTROL_OPTION_HANDLER\n");
|
||||||
|
if (control->length < sizeof(ppp_control_info) || !control->data)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
ppp_control_info *controlInfo = (ppp_control_info*) control->data;
|
||||||
|
KPPPOptionHandler *optionHandler = LCP().OptionHandlerAt(controlInfo->index);
|
||||||
|
if (!optionHandler) {
|
||||||
|
dprintf("optionHandler no avail\n");
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return optionHandler->Control(controlInfo->op, controlInfo->data,
|
||||||
|
controlInfo->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_CONTROL_LCP_EXTENSION:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_CONTROL_LCP_EXTENSION\n");
|
||||||
|
if (control->length < sizeof(ppp_control_info) || !control->data)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
ppp_control_info *controlInfo = (ppp_control_info*) control->data;
|
||||||
|
KPPPLCPExtension *lcpExtension = LCP().LCPExtensionAt(controlInfo->index);
|
||||||
|
if (!lcpExtension)
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
|
return lcpExtension->Control(controlInfo->op, controlInfo->data,
|
||||||
|
controlInfo->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
case PPPC_CONTROL_CHILD:
|
||||||
|
{
|
||||||
|
dprintf("PPPC_CONTROL_CHILD\n");
|
||||||
|
if (control->length < sizeof(ppp_control_info) || !control->data)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
ppp_control_info *controlInfo = (ppp_control_info*) control->data;
|
||||||
|
KPPPInterface *child = ChildAt(controlInfo->index);
|
||||||
|
if (!child)
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
|
||||||
|
return child->Control(controlInfo->op, controlInfo->data, controlInfo->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
default :
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
case PPPC_GET_INTERFACE_INFO:
|
case PPPC_GET_INTERFACE_INFO:
|
||||||
{
|
{
|
||||||
if (length < sizeof(ppp_interface_info_t) || !data)
|
if (length < sizeof(ppp_interface_info_t) || !data)
|
||||||
@@ -417,7 +721,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
|||||||
if (Name())
|
if (Name())
|
||||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||||
if (Ifnet())
|
if (Ifnet())
|
||||||
info->if_unit = Ifnet()->if_unit;
|
info->if_unit = Ifnet()->index;
|
||||||
else
|
else
|
||||||
info->if_unit = -1;
|
info->if_unit = -1;
|
||||||
info->mode = Mode();
|
info->mode = Mode();
|
||||||
@@ -456,7 +760,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
|||||||
if (!data)
|
if (!data)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
// login information can only be changed before we authenticate
|
// login information can only be changed before we authenticate
|
||||||
if (Phase() >= PPP_AUTHENTICATION_PHASE)
|
if (Phase() >= PPP_AUTHENTICATION_PHASE)
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
@@ -471,7 +775,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
|||||||
if (!data)
|
if (!data)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
// login information can only be changed before we authenticate
|
// login information can only be changed before we authenticate
|
||||||
if (Phase() >= PPP_AUTHENTICATION_PHASE)
|
if (Phase() >= PPP_AUTHENTICATION_PHASE)
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
@@ -524,7 +828,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
|||||||
if (length < sizeof(ppp_report_request) || !data)
|
if (length < sizeof(ppp_report_request) || !data)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
ppp_report_request *request = (ppp_report_request*) data;
|
ppp_report_request *request = (ppp_report_request*) data;
|
||||||
// first, we send an initial state report
|
// first, we send an initial state report
|
||||||
if (request->type == PPP_CONNECTION_REPORT) {
|
if (request->type == PPP_CONNECTION_REPORT) {
|
||||||
@@ -625,6 +929,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
dprintf("bad ppp_interface_control!\n");
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,7 +961,7 @@ KPPPInterface::SetDevice(KPPPDevice *device)
|
|||||||
return false;
|
return false;
|
||||||
// main interfaces do not have devices
|
// main interfaces do not have devices
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
if (Phase() != PPP_DOWN_PHASE)
|
if (Phase() != PPP_DOWN_PHASE)
|
||||||
return false;
|
return false;
|
||||||
@@ -704,7 +1009,7 @@ KPPPInterface::AddProtocol(KPPPProtocol *protocol)
|
|||||||
|| protocol->Level() == PPP_INTERFACE_LEVEL)
|
|| protocol->Level() == PPP_INTERFACE_LEVEL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
if (Phase() != PPP_DOWN_PHASE)
|
if (Phase() != PPP_DOWN_PHASE)
|
||||||
return false;
|
return false;
|
||||||
@@ -768,7 +1073,7 @@ KPPPInterface::RemoveProtocol(KPPPProtocol *protocol)
|
|||||||
TRACE("KPPPInterface: RemoveProtocol(%X)\n",
|
TRACE("KPPPInterface: RemoveProtocol(%X)\n",
|
||||||
protocol ? protocol->ProtocolNumber() : 0);
|
protocol ? protocol->ProtocolNumber() : 0);
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
if (Phase() != PPP_DOWN_PHASE)
|
if (Phase() != PPP_DOWN_PHASE)
|
||||||
return false;
|
return false;
|
||||||
@@ -809,7 +1114,7 @@ KPPPInterface::RemoveProtocol(KPPPProtocol *protocol)
|
|||||||
int32
|
int32
|
||||||
KPPPInterface::CountProtocols() const
|
KPPPInterface::CountProtocols() const
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
KPPPProtocol *protocol = FirstProtocol();
|
KPPPProtocol *protocol = FirstProtocol();
|
||||||
|
|
||||||
@@ -825,7 +1130,7 @@ KPPPInterface::CountProtocols() const
|
|||||||
KPPPProtocol*
|
KPPPProtocol*
|
||||||
KPPPInterface::ProtocolAt(int32 index) const
|
KPPPInterface::ProtocolAt(int32 index) const
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
KPPPProtocol *protocol = FirstProtocol();
|
KPPPProtocol *protocol = FirstProtocol();
|
||||||
|
|
||||||
@@ -849,7 +1154,8 @@ KPPPInterface::ProtocolFor(uint16 protocolNumber, KPPPProtocol *start) const
|
|||||||
{
|
{
|
||||||
TRACE("KPPPInterface: ProtocolFor(%X)\n", protocolNumber);
|
TRACE("KPPPInterface: ProtocolFor(%X)\n", protocolNumber);
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
// MutexLocker locker(fLock);
|
||||||
|
// already locked in ::Receive, uncomment this line will cause double lock
|
||||||
|
|
||||||
KPPPProtocol *current = start ? start : FirstProtocol();
|
KPPPProtocol *current = start ? start : FirstProtocol();
|
||||||
|
|
||||||
@@ -874,7 +1180,7 @@ KPPPInterface::AddChild(KPPPInterface *child)
|
|||||||
if (!child)
|
if (!child)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
if (fChildren.HasItem(child) || !fChildren.AddItem(child))
|
if (fChildren.HasItem(child) || !fChildren.AddItem(child))
|
||||||
return false;
|
return false;
|
||||||
@@ -891,7 +1197,7 @@ KPPPInterface::RemoveChild(KPPPInterface *child)
|
|||||||
{
|
{
|
||||||
TRACE("KPPPInterface: RemoveChild(%lX)\n", child ? child->ID() : 0);
|
TRACE("KPPPInterface: RemoveChild(%lX)\n", child ? child->ID() : 0);
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
if (!fChildren.RemoveItem(child))
|
if (!fChildren.RemoveItem(child))
|
||||||
return false;
|
return false;
|
||||||
@@ -912,7 +1218,7 @@ KPPPInterface::ChildAt(int32 index) const
|
|||||||
{
|
{
|
||||||
TRACE("KPPPInterface: ChildAt(%ld)\n", index);
|
TRACE("KPPPInterface: ChildAt(%ld)\n", index);
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
KPPPInterface *child = fChildren.ItemAt(index);
|
KPPPInterface *child = fChildren.ItemAt(index);
|
||||||
|
|
||||||
@@ -945,7 +1251,7 @@ KPPPInterface::SetConnectOnDemand(bool connectOnDemand)
|
|||||||
|
|
||||||
TRACE("KPPPInterface: SetConnectOnDemand(%s)\n", connectOnDemand ? "true" : "false");
|
TRACE("KPPPInterface: SetConnectOnDemand(%s)\n", connectOnDemand ? "true" : "false");
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
// Only clients support ConnectOnDemand.
|
// Only clients support ConnectOnDemand.
|
||||||
if (Mode() != PPP_CLIENT_MODE) {
|
if (Mode() != PPP_CLIENT_MODE) {
|
||||||
@@ -973,10 +1279,10 @@ KPPPInterface::SetConnectOnDemand(bool connectOnDemand)
|
|||||||
// check if we need to set/unset flags
|
// check if we need to set/unset flags
|
||||||
if (connectOnDemand) {
|
if (connectOnDemand) {
|
||||||
if (Ifnet())
|
if (Ifnet())
|
||||||
Ifnet()->if_flags |= IFF_UP;
|
Ifnet()->flags |= IFF_UP;
|
||||||
} else if (!connectOnDemand && Phase() < PPP_ESTABLISHED_PHASE) {
|
} else if (!connectOnDemand && Phase() < PPP_ESTABLISHED_PHASE) {
|
||||||
if (Ifnet())
|
if (Ifnet())
|
||||||
Ifnet()->if_flags &= ~IFF_UP;
|
Ifnet()->flags &= ~IFF_UP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -985,14 +1291,14 @@ KPPPInterface::SetConnectOnDemand(bool connectOnDemand)
|
|||||||
void
|
void
|
||||||
KPPPInterface::SetAskBeforeConnecting(bool ask)
|
KPPPInterface::SetAskBeforeConnecting(bool ask)
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
bool old = fAskBeforeConnecting;
|
bool old = fAskBeforeConnecting;
|
||||||
fAskBeforeConnecting = ask;
|
fAskBeforeConnecting = ask;
|
||||||
|
|
||||||
if (old && fAskBeforeConnecting == false && State() == PPP_STARTING_STATE
|
if (old && fAskBeforeConnecting == false && State() == PPP_STARTING_STATE
|
||||||
&& Phase() == PPP_DOWN_PHASE) {
|
&& Phase() == PPP_DOWN_PHASE) {
|
||||||
locker.UnlockNow();
|
// locker.Unlock();
|
||||||
StateMachine().ContinueOpenEvent();
|
StateMachine().ContinueOpenEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1004,7 +1310,7 @@ KPPPInterface::SetPFCOptions(uint8 pfcOptions)
|
|||||||
{
|
{
|
||||||
TRACE("KPPPInterface: SetPFCOptions(0x%X)\n", pfcOptions);
|
TRACE("KPPPInterface: SetPFCOptions(0x%X)\n", pfcOptions);
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
if (PFCOptions() & PPP_FREEZE_PFC_OPTIONS)
|
if (PFCOptions() & PPP_FREEZE_PFC_OPTIONS)
|
||||||
return false;
|
return false;
|
||||||
@@ -1032,7 +1338,7 @@ KPPPInterface::Up()
|
|||||||
if (IsUp())
|
if (IsUp())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
StateMachine().OpenEvent();
|
StateMachine().OpenEvent();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1059,7 +1365,7 @@ KPPPInterface::Down()
|
|||||||
send_data_with_timeout(fReconnectThread, 0, NULL, 0, 200);
|
send_data_with_timeout(fReconnectThread, 0, NULL, 0, 200);
|
||||||
// tell the reconnect thread to abort its attempt (if it's still waiting)
|
// tell the reconnect thread to abort its attempt (if it's still waiting)
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
StateMachine().CloseEvent();
|
StateMachine().CloseEvent();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1075,6 +1381,12 @@ KPPPInterface::WaitForConnection()
|
|||||||
if (InitCheck() != B_OK)
|
if (InitCheck() != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// just delay ~3 seconds to wait for ppp go up
|
||||||
|
for (uint32 i = 0; i < 10000; i++)
|
||||||
|
for (uint32 j = 0; j < 3000000; j++)
|
||||||
|
|
||||||
|
return true; // for temporary
|
||||||
|
|
||||||
ReportManager().EnableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
|
ReportManager().EnableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
|
||||||
|
|
||||||
ppp_report_packet report;
|
ppp_report_packet report;
|
||||||
@@ -1097,6 +1409,7 @@ KPPPInterface::WaitForConnection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReportManager().DisableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
|
ReportManager().DisableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
|
||||||
|
dprintf("KPPPInterface: WaitForConnection():%s\n", successful ? "True" : "False");
|
||||||
return successful;
|
return successful;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1233,7 +1546,7 @@ KPPPInterface::IsAllowedToSend() const
|
|||||||
- \c B_ERROR: Some error occured.
|
- \c B_ERROR: Some error occured.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
KPPPInterface::Send(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
TRACE("KPPPInterface: Send(0x%X)\n", protocolNumber);
|
TRACE("KPPPInterface: Send(0x%X)\n", protocolNumber);
|
||||||
|
|
||||||
@@ -1244,18 +1557,21 @@ KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
// do we have a device?
|
// do we have a device?
|
||||||
// did we load all modules?
|
// did we load all modules?
|
||||||
if (InitCheck() != B_OK) {
|
if (InitCheck() != B_OK) {
|
||||||
m_freem(packet);
|
ERROR("InitCheck() fail\n");
|
||||||
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// go up if ConnectOnDemand is enabled and we are disconnected
|
// go up if ConnectOnDemand is enabled and we are disconnected
|
||||||
// TODO: our new netstack will simplify ConnectOnDemand handling, so
|
// TODO: our new netstack will simplify ConnectOnDemand handling, so
|
||||||
// we do not have to handle it here
|
// we do not have to handle it here
|
||||||
if ((protocolNumber != PPP_LCP_PROTOCOL && DoesConnectOnDemand()
|
if ((protocolNumber != PPP_LCP_PROTOCOL && DoesConnectOnDemand()
|
||||||
&& (Phase() == PPP_DOWN_PHASE
|
&& (Phase() == PPP_DOWN_PHASE
|
||||||
|| Phase() == PPP_ESTABLISHMENT_PHASE)
|
|| Phase() == PPP_ESTABLISHMENT_PHASE)
|
||||||
&& !Up()) || !WaitForConnection()) {
|
&& !Up()) && !WaitForConnection()) {
|
||||||
m_freem(packet);
|
dprintf("DoesConnectOnDemand fail!\n");
|
||||||
|
// gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1279,52 +1595,61 @@ KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// make sure that protocol is allowed to send and everything is up
|
// make sure that protocol is allowed to send and everything is up
|
||||||
if (!Device()->IsUp() || !protocol || !protocol->IsEnabled()
|
if (Device()->IsUp() && protocolNumber == 0x0021) {
|
||||||
|
// IP_PROTOCOL 0x0021
|
||||||
|
TRACE("send IP packet!\n");
|
||||||
|
} else if (!Device()->IsUp() || !protocol || !protocol->IsEnabled()
|
||||||
|| !IsProtocolAllowed(*protocol)) {
|
|| !IsProtocolAllowed(*protocol)) {
|
||||||
ERROR("KPPPInterface::Send(): cannot send!\n");
|
ERROR("KPPPInterface::Send(): Device is down, throw packet away!!\n");
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// encode in ppp frame and consider using PFC
|
// encode in ppp frame and consider using PFC
|
||||||
if (UseLocalPFC() && protocolNumber & 0xFF00 == 0) {
|
if (UseLocalPFC() && (protocolNumber & 0xFF00) == 0) {
|
||||||
M_PREPEND(packet, 1);
|
TRACE("%s::%s should not go here\n", __FILE__, __func__);
|
||||||
|
NetBufferPrepend<uint8> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() != B_OK)
|
||||||
|
return bufferHeader.Status();
|
||||||
|
|
||||||
if (packet == NULL)
|
uint8 &header = bufferHeader.Data();
|
||||||
return B_ERROR;
|
|
||||||
|
// memcpy(header.destination, ether_pppoe_ppp_header, 1);
|
||||||
|
header = (protocolNumber & 0x00FF);
|
||||||
|
// bufferHeader.Sync();
|
||||||
|
|
||||||
uint8 *header = mtod(packet, uint8*);
|
|
||||||
*header = protocolNumber & 0xFF;
|
|
||||||
} else {
|
} else {
|
||||||
M_PREPEND(packet, 2);
|
NetBufferPrepend<uint16> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() != B_OK)
|
||||||
|
return bufferHeader.Status();
|
||||||
|
|
||||||
if (packet == NULL)
|
uint16 &header = bufferHeader.Data();
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
// set protocol (the only header field)
|
// set protocol (the only header field)
|
||||||
protocolNumber = htons(protocolNumber);
|
header = htons(protocolNumber);
|
||||||
uint16 *header = mtod(packet, uint16*);
|
// bufferHeader.Sync();
|
||||||
*header = protocolNumber;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pass to device if we're either not a multilink interface or a child interface
|
// pass to device if we're either not a multilink interface or a child interface
|
||||||
if (!IsMultilink() || Parent()) {
|
if (!IsMultilink() || Parent()) {
|
||||||
// check if packet is too big for device
|
// check if packet is too big for device
|
||||||
uint32 length = packet->m_flags & M_PKTHDR ? (uint32) packet->m_pkthdr.len :
|
uint32 length = packet->size;
|
||||||
packet->m_len;
|
|
||||||
|
|
||||||
if (length > MRU()) {
|
if (length > MRU()) {
|
||||||
m_freem(packet);
|
dprintf("packet too large!\n");
|
||||||
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_add64(&fStatistics.bytesSent, length);
|
atomic_add64(&fStatistics.bytesSent, length);
|
||||||
atomic_add64(&fStatistics.packetsSent, 1);
|
atomic_add64(&fStatistics.packetsSent, 1);
|
||||||
|
TRACE("%s::%s SendToNext\n", __FILE__, __func__);
|
||||||
return SendToNext(packet, 0);
|
return SendToNext(packet, 0);
|
||||||
// this is normally the device, but there can be something inbetween
|
// this is normally the device, but there can be something inbetween
|
||||||
} else {
|
} else {
|
||||||
// the multilink protocol should have sent it to some child interface
|
// the multilink protocol should have sent it to some child interface
|
||||||
m_freem(packet);
|
TRACE("It is weird to go here!\n");
|
||||||
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1348,25 +1673,37 @@ KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
- \c PPP_DISCARDED: The protocol handler(s) did not handle this packet.
|
- \c PPP_DISCARDED: The protocol handler(s) did not handle this packet.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
KPPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber)
|
KPPPInterface::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||||
{
|
{
|
||||||
TRACE("KPPPInterface: Receive(0x%X)\n", protocolNumber);
|
TRACE("KPPPInterface: Receive(0x%X)\n", protocolNumber);
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
int32 result = PPP_REJECTED;
|
int32 result = PPP_REJECTED;
|
||||||
// assume we have no handler
|
// assume we have no handler
|
||||||
|
|
||||||
// Set our interface as the receiver.
|
if (protocolNumber == 0x0021 && Device() && Device()->IsUp()) {
|
||||||
// The real netstack protocols (IP, IPX, etc.) might get confused if our
|
// IP_PROTOCOL 0x0021
|
||||||
// interface is a main interface and at the same time not registered
|
TRACE("%s::%s: receiving IP packet\n", __FILE__, __func__);
|
||||||
// because then there is no receiver interface.
|
ppp_device* dev=(ppp_device*)Ifnet();
|
||||||
// PPP NCPs should be aware of that!
|
|
||||||
if (packet->m_flags & M_PKTHDR && Ifnet() != NULL)
|
if (dev)
|
||||||
packet->m_pkthdr.rcvif = Ifnet();
|
return gStackModule->fifo_enqueue_buffer(&(dev->ppp_fifo), packet);
|
||||||
|
else {
|
||||||
|
dprintf("%s::%s: no ppp_device\n", __FILE__, __func__);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// // Set our interface as the receiver.
|
||||||
|
// // The real netstack protocols (IP, IPX, etc.) might get confused if our
|
||||||
|
// // interface is a main interface and at the same time not registered
|
||||||
|
// // because then there is no receiver interface.
|
||||||
|
// // PPP NCPs should be aware of that!
|
||||||
|
// if (packet->m_flags & M_PKTHDR && Ifnet() != NULL)
|
||||||
|
// packet->m_pkthdr.rcvif = Ifnet();
|
||||||
|
|
||||||
// Find handler and let it parse the packet.
|
// Find handler and let it parse the packet.
|
||||||
// The handler does need not be up because if we are a server
|
// The handler does need not be up because if we are a server
|
||||||
@@ -1396,7 +1733,7 @@ KPPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
return Parent()->Receive(packet, protocolNumber);
|
return Parent()->Receive(packet, protocolNumber);
|
||||||
|
|
||||||
if (result == PPP_UNHANDLED) {
|
if (result == PPP_UNHANDLED) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return PPP_DISCARDED;
|
return PPP_DISCARDED;
|
||||||
} else {
|
} else {
|
||||||
StateMachine().RUCEvent(packet, protocolNumber);
|
StateMachine().RUCEvent(packet, protocolNumber);
|
||||||
@@ -1419,7 +1756,7 @@ KPPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
- \c PPP_DISCARDED: The protocol handler(s) did not handle this packet.
|
- \c PPP_DISCARDED: The protocol handler(s) did not handle this packet.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
KPPPInterface::ReceiveFromDevice(struct mbuf *packet)
|
KPPPInterface::ReceiveFromDevice(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPInterface: ReceiveFromDevice()\n");
|
TRACE("KPPPInterface: ReceiveFromDevice()\n");
|
||||||
|
|
||||||
@@ -1427,20 +1764,37 @@ KPPPInterface::ReceiveFromDevice(struct mbuf *packet)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
if (InitCheck() != B_OK) {
|
if (InitCheck() != B_OK) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 length = packet->m_flags & M_PKTHDR ? (uint32) packet->m_pkthdr.len :
|
uint32 length = packet->size;
|
||||||
packet->m_len;
|
|
||||||
|
|
||||||
// decode ppp frame and recognize PFC
|
// decode ppp frame and recognize PFC
|
||||||
uint16 protocolNumber = *mtod(packet, uint8*);
|
NetBufferHeaderReader<uint16> bufferHeader(packet);
|
||||||
if (protocolNumber & 1) {
|
if (bufferHeader.Status() < B_OK)
|
||||||
m_adj(packet, 1);
|
return bufferHeader.Status();
|
||||||
|
|
||||||
|
uint16 &header = bufferHeader.Data();
|
||||||
|
uint16 protocolNumber = ntohs(header); // copy the protocol number
|
||||||
|
TRACE("%s::%s: ppp protocol number:%x\n", __FILE__, __func__, protocolNumber);
|
||||||
|
|
||||||
|
bufferHeader.Remove();
|
||||||
|
bufferHeader.Sync();
|
||||||
|
|
||||||
|
// PFC only use 1 byte for protocol, the next byte is in first byte of message
|
||||||
|
if (protocolNumber & (1UL<<8)) {
|
||||||
|
NetBufferPrepend<uint8> bufferprepend(packet);
|
||||||
|
if (bufferprepend.Status() < B_OK) {
|
||||||
|
gBufferModule->free(packet);
|
||||||
|
return bufferprepend.Status();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 &prepend = bufferprepend.Data();
|
||||||
|
prepend = (uint8)(protocolNumber & 0x00FF);
|
||||||
|
// bufferprepend.Sync();
|
||||||
|
TRACE("%s::%s:PFC protocol:%x\n", __FILE__, __func__, protocolNumber>>8);
|
||||||
} else {
|
} else {
|
||||||
protocolNumber = ntohs(*mtod(packet, uint16*));
|
TRACE("%s::%s:Non-PFC protocol:%x\n", __FILE__, __func__, protocolNumber);
|
||||||
m_adj(packet, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_add64(&fStatistics.bytesReceived, length);
|
atomic_add64(&fStatistics.bytesReceived, length);
|
||||||
@@ -1453,7 +1807,7 @@ KPPPInterface::ReceiveFromDevice(struct mbuf *packet)
|
|||||||
void
|
void
|
||||||
KPPPInterface::Pulse()
|
KPPPInterface::Pulse()
|
||||||
{
|
{
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
if (Device())
|
if (Device())
|
||||||
Device()->Pulse();
|
Device()->Pulse();
|
||||||
@@ -1485,7 +1839,7 @@ KPPPInterface::RegisterInterface()
|
|||||||
return true;
|
return true;
|
||||||
// we are already registered
|
// we are already registered
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
// only MainInterfaces get an ifnet
|
// only MainInterfaces get an ifnet
|
||||||
if (IsMultilink() && Parent() && Parent()->RegisterInterface())
|
if (IsMultilink() && Parent() && Parent()->RegisterInterface())
|
||||||
@@ -1496,11 +1850,13 @@ KPPPInterface::RegisterInterface()
|
|||||||
|
|
||||||
fIfnet = fManager->RegisterInterface(ID());
|
fIfnet = fManager->RegisterInterface(ID());
|
||||||
|
|
||||||
if (!fIfnet)
|
if (!fIfnet) {
|
||||||
|
dprintf("%s:%s: damn it no fIfnet device\n", __FILE__, __func__);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (DoesConnectOnDemand())
|
if (DoesConnectOnDemand())
|
||||||
fIfnet->if_flags |= IFF_UP;
|
fIfnet->flags |= IFF_UP;
|
||||||
|
|
||||||
CalculateInterfaceMTU();
|
CalculateInterfaceMTU();
|
||||||
CalculateBaudRate();
|
CalculateBaudRate();
|
||||||
@@ -1519,7 +1875,7 @@ KPPPInterface::UnregisterInterface()
|
|||||||
return true;
|
return true;
|
||||||
// we are already unregistered
|
// we are already unregistered
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
// only MainInterfaces get an ifnet
|
// only MainInterfaces get an ifnet
|
||||||
if (IsMultilink() && Parent())
|
if (IsMultilink() && Parent())
|
||||||
@@ -1587,7 +1943,7 @@ KPPPInterface::StackControlEachHandler(uint32 op, void *data)
|
|||||||
|
|
||||||
status_t result = B_BAD_VALUE, tmp;
|
status_t result = B_BAD_VALUE, tmp;
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
KPPPProtocol *protocol = FirstProtocol();
|
KPPPProtocol *protocol = FirstProtocol();
|
||||||
for (; protocol; protocol = protocol->NextProtocol()) {
|
for (; protocol; protocol = protocol->NextProtocol()) {
|
||||||
@@ -1613,7 +1969,9 @@ KPPPInterface::CalculateInterfaceMTU()
|
|||||||
{
|
{
|
||||||
TRACE("KPPPInterface: CalculateInterfaceMTU()\n");
|
TRACE("KPPPInterface: CalculateInterfaceMTU()\n");
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
// MutexLocker locker(fLock);
|
||||||
|
// uncomment this line will cause double lock
|
||||||
|
// alreay locked in ::KPPPInterface
|
||||||
|
|
||||||
fInterfaceMTU = fMRU;
|
fInterfaceMTU = fMRU;
|
||||||
fHeaderLength = 2;
|
fHeaderLength = 2;
|
||||||
@@ -1628,8 +1986,9 @@ KPPPInterface::CalculateInterfaceMTU()
|
|||||||
fInterfaceMTU -= fHeaderLength;
|
fInterfaceMTU -= fHeaderLength;
|
||||||
|
|
||||||
if (Ifnet()) {
|
if (Ifnet()) {
|
||||||
Ifnet()->if_mtu = fInterfaceMTU;
|
Ifnet()->mtu = fInterfaceMTU;
|
||||||
Ifnet()->if_hdrlen = fHeaderLength;
|
Ifnet()->header_length = fHeaderLength;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Parent())
|
if (Parent())
|
||||||
@@ -1643,19 +2002,20 @@ KPPPInterface::CalculateBaudRate()
|
|||||||
{
|
{
|
||||||
TRACE("KPPPInterface: CalculateBaudRate()\n");
|
TRACE("KPPPInterface: CalculateBaudRate()\n");
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
// MutexLocker locker(fLock); // uncomment this will cause double lock
|
||||||
|
|
||||||
if (!Ifnet())
|
if (!Ifnet())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Device())
|
if (Device())
|
||||||
fIfnet->if_baudrate = max_c(Device()->InputTransferRate(),
|
fIfnet->link_speed = max_c(Device()->InputTransferRate(),
|
||||||
Device()->OutputTransferRate());
|
Device()->OutputTransferRate());
|
||||||
else {
|
else {
|
||||||
fIfnet->if_baudrate = 0;
|
fIfnet->link_speed = 0;
|
||||||
for (int32 index = 0; index < CountChildren(); index++)
|
for (int32 index = 0; index < CountChildren(); index++)
|
||||||
if (ChildAt(index)->Ifnet())
|
if (ChildAt(index)->Ifnet())
|
||||||
fIfnet->if_baudrate += ChildAt(index)->Ifnet()->if_baudrate;
|
fIfnet->link_speed += ChildAt(index)->Ifnet()->link_speed;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1666,7 +2026,7 @@ KPPPInterface::Reconnect(uint32 delay)
|
|||||||
{
|
{
|
||||||
TRACE("KPPPInterface: Reconnect(%ld)\n", delay);
|
TRACE("KPPPInterface: Reconnect(%ld)\n", delay);
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
if (fReconnectThread != -1)
|
if (fReconnectThread != -1)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -87,6 +90,7 @@ 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())
|
||||||
@@ -160,6 +164,7 @@ 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())
|
||||||
@@ -196,22 +201,6 @@ KPPPLCP::LCPExtensionFor(uint8 code, int32 *start) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! 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,7 +230,7 @@ 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;
|
||||||
@@ -251,29 +240,22 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
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)
|
|
||||||
length = packet->m_pkthdr.len;
|
|
||||||
length -= ntohs(data->length);
|
|
||||||
if (length)
|
|
||||||
m_adj(packet, -length);
|
|
||||||
|
|
||||||
struct mbuf *copy = m_gethdr(MT_DATA);
|
net_buffer *copy = gBufferModule->duplicate(packet);
|
||||||
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)
|
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,7 +292,7 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
m_freem(packet);
|
// gBufferModule->free(packet);
|
||||||
handled = false;
|
handled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,18 +306,18 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,7 +327,7 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
|||||||
return PPP_REJECTED;
|
return PPP_REJECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,10 +19,12 @@
|
|||||||
|
|
||||||
#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.
|
||||||
|
|
||||||
@@ -56,7 +58,7 @@ 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;
|
||||||
@@ -70,7 +72,7 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|
||||||
@@ -33,7 +35,7 @@ report_sender_thread(void *data)
|
|||||||
|
|
||||||
\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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -88,7 +90,7 @@ 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;
|
||||||
@@ -106,7 +108,7 @@ 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;
|
||||||
|
|
||||||
@@ -135,7 +137,7 @@ 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;
|
||||||
|
|
||||||
@@ -177,7 +179,7 @@ KPPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 le
|
|||||||
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);
|
||||||
|
|||||||
@@ -22,8 +22,12 @@
|
|||||||
#include <KPPPUtils.h>
|
#include <KPPPUtils.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <core_funcs.h>
|
|
||||||
|
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <net_buffer.h>
|
||||||
|
#include <NetBufferUtilities.h>
|
||||||
|
|
||||||
|
extern net_buffer_module_info *gBufferModule;
|
||||||
|
|
||||||
static const bigtime_t kPPPStateMachineTimeout = 3000000;
|
static const bigtime_t kPPPStateMachineTimeout = 3000000;
|
||||||
// 3 seconds
|
// 3 seconds
|
||||||
@@ -49,8 +53,9 @@ KPPPStateMachine::KPPPStateMachine(KPPPInterface& interface)
|
|||||||
fTerminateID(0),
|
fTerminateID(0),
|
||||||
fEchoID(0),
|
fEchoID(0),
|
||||||
fNextTimeout(0),
|
fNextTimeout(0),
|
||||||
fLock("KPPPStateMachine")
|
fLock(mutex())
|
||||||
{
|
{
|
||||||
|
mutex_init(&fLock, "KPPPStateMachine");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -114,8 +119,8 @@ KPPPStateMachine::NewPhase(ppp_phase next)
|
|||||||
// The report threads get their notification later.
|
// The report threads get their notification later.
|
||||||
if (Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) {
|
if (Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) {
|
||||||
if (Interface().Ifnet()) {
|
if (Interface().Ifnet()) {
|
||||||
Interface().Ifnet()->if_flags &= ~IFF_RUNNING;
|
// Interface().Ifnet()->flags &= ~IFF_RUNNING;
|
||||||
Interface().Ifnet()->if_flags &= ~IFF_UP;
|
Interface().Ifnet()->flags &= ~IFF_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Interface().Parent())
|
if (Interface().Parent())
|
||||||
@@ -128,7 +133,7 @@ KPPPStateMachine::NewPhase(ppp_phase next)
|
|||||||
Interface().fConnectedSince = system_time();
|
Interface().fConnectedSince = system_time();
|
||||||
|
|
||||||
if (Interface().Ifnet())
|
if (Interface().Ifnet())
|
||||||
Interface().Ifnet()->if_flags |= IFF_UP | IFF_RUNNING;
|
Interface().Ifnet()->flags |= IFF_UP;// | IFF_RUNNING;
|
||||||
|
|
||||||
Interface().fConnectAttempt = 0;
|
Interface().fConnectAttempt = 0;
|
||||||
// when we Reconnect() this becomes 1 (the first connection attempt)
|
// when we Reconnect() this becomes 1 (the first connection attempt)
|
||||||
@@ -172,20 +177,32 @@ KPPPStateMachine::SendEchoRequest()
|
|||||||
if (State() != PPP_OPENED_STATE)
|
if (State() != PPP_OPENED_STATE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
net_buffer *packet = gBufferModule->create(256);
|
||||||
if (!packet)
|
if (packet == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
packet->m_data += LCP().AdditionalOverhead();
|
void *data;
|
||||||
packet->m_pkthdr.len = packet->m_len = 8;
|
status_t status = gBufferModule->append_size(packet, 1492, &data);
|
||||||
// echo requests are at least eight bytes long
|
if (status == B_OK && data == NULL) {
|
||||||
|
gBufferModule->free(packet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
// echo requests are at least eight bytes long
|
||||||
request->code = PPP_ECHO_REQUEST;
|
ppp_lcp_packet request;
|
||||||
request->id = NextID();
|
request.code = PPP_ECHO_REQUEST;
|
||||||
fEchoID = request->id;
|
request.id = NextID();
|
||||||
request->length = htons(packet->m_len);
|
request.length = htons(8);
|
||||||
memcpy(request->data, &fMagicNumber, sizeof(fMagicNumber));
|
fEchoID = request.id;
|
||||||
|
|
||||||
|
memcpy(data, &request, sizeof(request));
|
||||||
|
memcpy(request.data, &fMagicNumber, sizeof(fMagicNumber));
|
||||||
|
|
||||||
|
status = gBufferModule->trim(packet, sizeof(request) + sizeof(fMagicNumber));
|
||||||
|
if (status < B_OK) {
|
||||||
|
gBufferModule->free(packet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return LCP().Send(packet) == B_OK;
|
return LCP().Send(packet) == B_OK;
|
||||||
}
|
}
|
||||||
@@ -197,22 +214,33 @@ KPPPStateMachine::SendDiscardRequest()
|
|||||||
{
|
{
|
||||||
TRACE("KPPPSM: SendDiscardRequest() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: SendDiscardRequest() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
if (State() != PPP_OPENED_STATE)
|
net_buffer *packet = gBufferModule->create(256);
|
||||||
|
if (packet == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
void *data;
|
||||||
if (!packet)
|
status_t status = gBufferModule->append_size(packet, 1492, &data);
|
||||||
|
if (status == B_OK && data == NULL) {
|
||||||
|
gBufferModule->free(packet);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
packet->m_data += LCP().AdditionalOverhead();
|
|
||||||
packet->m_pkthdr.len = packet->m_len = 8;
|
|
||||||
// discard requests are at least eight bytes long
|
// discard requests are at least eight bytes long
|
||||||
|
// echo requests are at least eight bytes long
|
||||||
|
ppp_lcp_packet request;
|
||||||
|
request.code = PPP_DISCARD_REQUEST;
|
||||||
|
request.id = NextID();
|
||||||
|
request.length = htons(8);
|
||||||
|
fEchoID = request.id;
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
memcpy(data, &request, sizeof(request));
|
||||||
request->code = PPP_DISCARD_REQUEST;
|
memcpy(request.data, &fMagicNumber, sizeof(fMagicNumber));
|
||||||
request->id = NextID();
|
|
||||||
request->length = htons(packet->m_len);
|
status = gBufferModule->trim(packet, sizeof(request) + sizeof(fMagicNumber));
|
||||||
memcpy(request->data, &fMagicNumber, sizeof(fMagicNumber));
|
if (status < B_OK) {
|
||||||
|
gBufferModule->free(packet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return LCP().Send(packet) == B_OK;
|
return LCP().Send(packet) == B_OK;
|
||||||
}
|
}
|
||||||
@@ -893,42 +921,49 @@ KPPPStateMachine::TOBadEvent()
|
|||||||
|
|
||||||
// receive configure request (acceptable request)
|
// receive configure request (acceptable request)
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
KPPPStateMachine::RCRGoodEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RCRGoodEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RCRGoodEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
switch (State()) {
|
switch (State()) {
|
||||||
case PPP_INITIAL_STATE:
|
case PPP_INITIAL_STATE:
|
||||||
case PPP_STARTING_STATE:
|
case PPP_STARTING_STATE:
|
||||||
|
TRACE("%s::%s: PPP_STARTING_STATE\n", __FILE__, __func__);
|
||||||
IllegalEvent(PPP_RCR_GOOD_EVENT);
|
IllegalEvent(PPP_RCR_GOOD_EVENT);
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_CLOSED_STATE:
|
case PPP_CLOSED_STATE:
|
||||||
|
TRACE("%s::%s: PPP_CLOSED_STATE\n", __FILE__, __func__);
|
||||||
SendTerminateAck();
|
SendTerminateAck();
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_STOPPED_STATE:
|
case PPP_STOPPED_STATE:
|
||||||
|
TRACE("%s::%s: PPP_STOPPED_STATE\n", __FILE__, __func__);
|
||||||
// irc,scr,sca/8
|
// irc,scr,sca/8
|
||||||
// XXX: should we do nothing and wait for DownEvent()?
|
// XXX: should we do nothing and wait for DownEvent()?
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_REQ_SENT_STATE:
|
case PPP_REQ_SENT_STATE:
|
||||||
NewState(PPP_ACK_SENT_STATE);
|
NewState(PPP_ACK_SENT_STATE);
|
||||||
|
|
||||||
case PPP_ACK_SENT_STATE:
|
case PPP_ACK_SENT_STATE:
|
||||||
|
TRACE("%s::%s: PPP_ACK_SENT_STATE size %ld\n", __FILE__, __func__,
|
||||||
|
packet->size);
|
||||||
SendConfigureAck(packet);
|
SendConfigureAck(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
|
TRACE("%s::%s: PPP_ACK_RCVD_STATE\n", __FILE__, __func__);
|
||||||
NewState(PPP_OPENED_STATE);
|
NewState(PPP_OPENED_STATE);
|
||||||
SendConfigureAck(packet);
|
SendConfigureAck(packet);
|
||||||
ThisLayerUp();
|
ThisLayerUp();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_OPENED_STATE:
|
case PPP_OPENED_STATE:
|
||||||
|
TRACE("%s::%s: PPP_OPENED_STATE\n", __FILE__, __func__);
|
||||||
NewState(PPP_ACK_SENT_STATE);
|
NewState(PPP_ACK_SENT_STATE);
|
||||||
NewPhase(PPP_ESTABLISHMENT_PHASE);
|
NewPhase(PPP_ESTABLISHMENT_PHASE);
|
||||||
// indicates to handlers that we are reconfiguring
|
// indicates to handlers that we are reconfiguring
|
||||||
@@ -938,17 +973,21 @@ KPPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
m_freem(packet);
|
TRACE("free peer's ppp request packet\n");
|
||||||
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// receive configure request (unacceptable request)
|
// receive configure request (unacceptable request)
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
KPPPStateMachine::RCRBadEvent(net_buffer *nak, net_buffer *reject)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RCRBadEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RCRBadEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
|
uint16 lenNak = 0;
|
||||||
|
uint16 lenReject = 0;
|
||||||
|
|
||||||
switch (State()) {
|
switch (State()) {
|
||||||
case PPP_INITIAL_STATE:
|
case PPP_INITIAL_STATE:
|
||||||
case PPP_STARTING_STATE:
|
case PPP_STARTING_STATE:
|
||||||
@@ -978,9 +1017,25 @@ KPPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
|||||||
|
|
||||||
case PPP_REQ_SENT_STATE:
|
case PPP_REQ_SENT_STATE:
|
||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
if (nak && ntohs(mtod(nak, ppp_lcp_packet*)->length) > 3)
|
if (nak) {
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> nakBufferHeader(nak);
|
||||||
|
if (nakBufferHeader.Status() < B_OK)
|
||||||
|
break;
|
||||||
|
ppp_lcp_packet &nakHeader = nakBufferHeader.Data();
|
||||||
|
lenNak = nakHeader.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reject) {
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> rejectBufferHeader(reject);
|
||||||
|
if (rejectBufferHeader.Status() < B_OK)
|
||||||
|
break;
|
||||||
|
ppp_lcp_packet &rejectHeader = rejectBufferHeader.Data();
|
||||||
|
lenReject = rejectHeader.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nak && lenNak > 3)
|
||||||
SendConfigureNak(nak);
|
SendConfigureNak(nak);
|
||||||
else if (reject && ntohs(mtod(reject, ppp_lcp_packet*)->length) > 3)
|
else if (reject && lenReject > 3)
|
||||||
SendConfigureNak(reject);
|
SendConfigureNak(reject);
|
||||||
return;
|
return;
|
||||||
// prevents the nak/reject from being m_freem()'d
|
// prevents the nak/reject from being m_freem()'d
|
||||||
@@ -990,24 +1045,29 @@ KPPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nak)
|
if (nak)
|
||||||
m_freem(nak);
|
gBufferModule->free(nak);
|
||||||
if (reject)
|
if (reject)
|
||||||
m_freem(reject);
|
gBufferModule->free(reject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// receive configure ack
|
// receive configure ack
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RCAEvent(struct mbuf *packet)
|
KPPPStateMachine::RCAEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RCAEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RCAEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
if (fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &header = bufferHeader.Data();
|
||||||
|
|
||||||
|
if (fRequestID != header.id) {
|
||||||
// this packet is not a reply to our request
|
// this packet is not a reply to our request
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// log this event
|
// log this event
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1017,7 +1077,7 @@ KPPPStateMachine::RCAEvent(struct mbuf *packet)
|
|||||||
for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||||
optionHandler = LCP().OptionHandlerAt(index);
|
optionHandler = LCP().OptionHandlerAt(index);
|
||||||
if (optionHandler->ParseAck(ack) != B_OK) {
|
if (optionHandler->ParseAck(ack) != B_OK) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1062,22 +1122,27 @@ KPPPStateMachine::RCAEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// receive configure nak/reject
|
// receive configure nak/reject
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RCNEvent(struct mbuf *packet)
|
KPPPStateMachine::RCNEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RCNEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RCNEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
if (fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &header = bufferHeader.Data();
|
||||||
|
|
||||||
|
if (fRequestID != header.id) {
|
||||||
// this packet is not a reply to our request
|
// this packet is not a reply to our request
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// log this event
|
// log this event
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1089,13 +1154,13 @@ KPPPStateMachine::RCNEvent(struct mbuf *packet)
|
|||||||
|
|
||||||
if (nak_reject.Code() == PPP_CONFIGURE_NAK) {
|
if (nak_reject.Code() == PPP_CONFIGURE_NAK) {
|
||||||
if (optionHandler->ParseNak(nak_reject) != B_OK) {
|
if (optionHandler->ParseNak(nak_reject) != B_OK) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (nak_reject.Code() == PPP_CONFIGURE_REJECT) {
|
} else if (nak_reject.Code() == PPP_CONFIGURE_REJECT) {
|
||||||
if (optionHandler->ParseReject(nak_reject) != B_OK) {
|
if (optionHandler->ParseReject(nak_reject) != B_OK) {
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1135,18 +1200,23 @@ KPPPStateMachine::RCNEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// receive terminate request
|
// receive terminate request
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RTREvent(struct mbuf *packet)
|
KPPPStateMachine::RTREvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RTREvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RTREvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &header = bufferHeader.Data();
|
||||||
|
|
||||||
// we should not use the same ID as the peer
|
// we should not use the same ID as the peer
|
||||||
if (fID == mtod(packet, ppp_lcp_packet*)->id)
|
if (fID == header.id)
|
||||||
fID -= 128;
|
fID -= 128;
|
||||||
|
|
||||||
fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
||||||
@@ -1156,7 +1226,7 @@ KPPPStateMachine::RTREvent(struct mbuf *packet)
|
|||||||
case PPP_INITIAL_STATE:
|
case PPP_INITIAL_STATE:
|
||||||
case PPP_STARTING_STATE:
|
case PPP_STARTING_STATE:
|
||||||
IllegalEvent(PPP_RTR_EVENT);
|
IllegalEvent(PPP_RTR_EVENT);
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_ACK_RCVD_STATE:
|
case PPP_ACK_RCVD_STATE:
|
||||||
@@ -1186,16 +1256,21 @@ KPPPStateMachine::RTREvent(struct mbuf *packet)
|
|||||||
|
|
||||||
// receive terminate ack
|
// receive terminate ack
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RTAEvent(struct mbuf *packet)
|
KPPPStateMachine::RTAEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RTAEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RTAEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
if (fTerminateID != mtod(packet, ppp_lcp_packet*)->id) {
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &header = bufferHeader.Data();
|
||||||
|
|
||||||
|
if (fTerminateID != header.id) {
|
||||||
// this packet is not a reply to our request
|
// this packet is not a reply to our request
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// log this event
|
// log this event
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1231,13 +1306,13 @@ KPPPStateMachine::RTAEvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// receive unknown code
|
// receive unknown code
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
KPPPStateMachine::RUCEvent(net_buffer *packet, uint16 protocolNumber,
|
||||||
uint8 code)
|
uint8 code)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RUCEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RUCEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
@@ -1246,7 +1321,7 @@ KPPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
|||||||
case PPP_INITIAL_STATE:
|
case PPP_INITIAL_STATE:
|
||||||
case PPP_STARTING_STATE:
|
case PPP_STARTING_STATE:
|
||||||
IllegalEvent(PPP_RUC_EVENT);
|
IllegalEvent(PPP_RUC_EVENT);
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1257,7 +1332,7 @@ KPPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
|||||||
|
|
||||||
// receive code/protocol reject (acceptable such as IPX reject)
|
// receive code/protocol reject (acceptable such as IPX reject)
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RXJGoodEvent(struct mbuf *packet)
|
KPPPStateMachine::RXJGoodEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RXJGoodEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RXJGoodEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
@@ -1282,7 +1357,7 @@ KPPPStateMachine::RXJGoodEvent(struct mbuf *packet)
|
|||||||
|
|
||||||
// receive code/protocol reject (catastrophic such as LCP reject)
|
// receive code/protocol reject (catastrophic such as LCP reject)
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
KPPPStateMachine::RXJBadEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RXJBadEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RXJBadEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
@@ -1321,19 +1396,22 @@ KPPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// receive echo request/reply, discard request
|
// receive echo request/reply, discard request
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RXREvent(struct mbuf *packet)
|
KPPPStateMachine::RXREvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RXREvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RXREvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
ppp_lcp_packet *echo = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &echo = bufferHeader.Data();
|
||||||
|
|
||||||
if (echo->code == PPP_ECHO_REPLY && echo->id != fEchoID) {
|
if (echo.code == PPP_ECHO_REPLY && echo.id != fEchoID) {
|
||||||
// TODO:
|
// TODO:
|
||||||
// log that we got a reply, but no request was sent
|
// log that we got a reply, but no request was sent
|
||||||
}
|
}
|
||||||
@@ -1345,7 +1423,7 @@ KPPPStateMachine::RXREvent(struct mbuf *packet)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PPP_OPENED_STATE:
|
case PPP_OPENED_STATE:
|
||||||
if (echo->code == PPP_ECHO_REQUEST)
|
if (echo.code == PPP_ECHO_REQUEST)
|
||||||
SendEchoReply(packet);
|
SendEchoReply(packet);
|
||||||
return;
|
return;
|
||||||
// this prevents the packet from being freed
|
// this prevents the packet from being freed
|
||||||
@@ -1354,7 +1432,7 @@ KPPPStateMachine::RXREvent(struct mbuf *packet)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1397,20 +1475,27 @@ KPPPStateMachine::TimerEvent()
|
|||||||
|
|
||||||
|
|
||||||
// ReceiveConfigureRequest
|
// ReceiveConfigureRequest
|
||||||
// Here we get a configure-request packet from LCP and aks all OptionHandlers
|
// Here we get a configure-request packet from LCP and ask all OptionHandlers
|
||||||
// if its values are acceptable. From here we call our Good/Bad counterparts.
|
// if its values are acceptable. From here we call our Good/Bad counterparts.
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RCREvent(struct mbuf *packet)
|
KPPPStateMachine::RCREvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RCREvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RCREvent() state=%d phase=%d lcppacket size=%ld\n", State(), Phase(),
|
||||||
|
packet->size);
|
||||||
|
|
||||||
KPPPConfigurePacket request(packet);
|
KPPPConfigurePacket request(packet);
|
||||||
KPPPConfigurePacket nak(PPP_CONFIGURE_NAK);
|
KPPPConfigurePacket nak(PPP_CONFIGURE_NAK);
|
||||||
KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT);
|
KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT);
|
||||||
|
|
||||||
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &header = bufferHeader.Data();
|
||||||
|
|
||||||
// we should not use the same id as the peer
|
// we should not use the same id as the peer
|
||||||
if (fID == mtod(packet, ppp_lcp_packet*)->id)
|
if (fID == header.id)
|
||||||
fID -= 128;
|
fID -= 128;
|
||||||
|
// or maybe we should use peer's ID plus 1 ?
|
||||||
|
|
||||||
nak.SetID(request.ID());
|
nak.SetID(request.ID());
|
||||||
reject.SetID(request.ID());
|
reject.SetID(request.ID());
|
||||||
@@ -1423,11 +1508,23 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
|
optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
|
||||||
|
|
||||||
if (!optionHandler || !optionHandler->IsEnabled()) {
|
if (!optionHandler || !optionHandler->IsEnabled()) {
|
||||||
ERROR("KPPPSM::RCREvent():unknown type:%d\n", request.ItemAt(index)->type);
|
TRACE("KPPPSM::RCREvent():unknown type:%d\n", request.ItemAt(index)->type);
|
||||||
|
if (request.ItemAt(index)->type == 0x5)
|
||||||
|
{
|
||||||
|
// type 0x5 is Magic Number, Need no processing.
|
||||||
|
TRACE("Peer Magic Number:%02x %02x %02x %02x\n",
|
||||||
|
(request.ItemAt(index)->data)[0],
|
||||||
|
(request.ItemAt(index)->data)[1],
|
||||||
|
(request.ItemAt(index)->data)[2],
|
||||||
|
(request.ItemAt(index)->data)[3]);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
// unhandled items should be added to the reject
|
// unhandled items should be added to the reject
|
||||||
|
TRACE("why come here %ld\n", index);
|
||||||
reject.AddItem(request.ItemAt(index));
|
reject.AddItem(request.ItemAt(index));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("KPPPSM::RCREvent(): OH=%s\n",
|
TRACE("KPPPSM::RCREvent(): OH=%s\n",
|
||||||
optionHandler->Name() ? optionHandler->Name() : "Unknown");
|
optionHandler->Name() ? optionHandler->Name() : "Unknown");
|
||||||
@@ -1435,13 +1532,14 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
|
|
||||||
if (result == PPP_UNHANDLED) {
|
if (result == PPP_UNHANDLED) {
|
||||||
// unhandled items should be added to the reject
|
// unhandled items should be added to the reject
|
||||||
|
TRACE("PPP_UNHANDLED %ld\n", index);
|
||||||
reject.AddItem(request.ItemAt(index));
|
reject.AddItem(request.ItemAt(index));
|
||||||
continue;
|
continue;
|
||||||
} else if (result != B_OK) {
|
} else if (result != B_OK) {
|
||||||
// the request contains a value that has been sent more than
|
// the request contains a value that has been sent more than
|
||||||
// once or the value is corrupted
|
// once or the value is corrupted
|
||||||
ERROR("KPPPSM::RCREvent(): OptionHandler returned parse error!\n");
|
ERROR("KPPPSM::RCREvent(): OptionHandler returned parse error!\n");
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1460,7 +1558,7 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
// the request contains a value that has been sent more than
|
// the request contains a value that has been sent more than
|
||||||
// once or the value is corrupted
|
// once or the value is corrupted
|
||||||
ERROR("KPPPSM::RCREvent():OptionHandler returned append error!\n");
|
ERROR("KPPPSM::RCREvent():OptionHandler returned append error!\n");
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1469,11 +1567,13 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (reject.CountItems() > 0) {
|
if (reject.CountItems() > 0) {
|
||||||
RCRBadEvent(NULL, reject.ToMbuf(Interface().MRU(), LCP().AdditionalOverhead()));
|
TRACE("%s:reject number more than 0\n", __func__);
|
||||||
m_freem(packet);
|
RCRBadEvent(NULL, reject.ToNetBuffer(Interface().MRU()));
|
||||||
|
gBufferModule->free(packet);
|
||||||
} else if (nak.CountItems() > 0) {
|
} else if (nak.CountItems() > 0) {
|
||||||
RCRBadEvent(nak.ToMbuf(Interface().MRU(), LCP().AdditionalOverhead()), NULL);
|
TRACE("%s:nak number more than 0\n", __func__);
|
||||||
m_freem(packet);
|
RCRBadEvent(nak.ToNetBuffer(Interface().MRU()), NULL);
|
||||||
|
gBufferModule->free(packet);
|
||||||
} else
|
} else
|
||||||
RCRGoodEvent(packet);
|
RCRGoodEvent(packet);
|
||||||
}
|
}
|
||||||
@@ -1483,21 +1583,24 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
|||||||
// LCP received a code/protocol-reject packet and we look if it is acceptable.
|
// LCP received a code/protocol-reject packet and we look if it is acceptable.
|
||||||
// From here we call our Good/Bad counterparts.
|
// From here we call our Good/Bad counterparts.
|
||||||
void
|
void
|
||||||
KPPPStateMachine::RXJEvent(struct mbuf *packet)
|
KPPPStateMachine::RXJEvent(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: RXJEvent() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: RXJEvent() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return;
|
||||||
|
ppp_lcp_packet &reject = bufferHeader.Data();
|
||||||
|
|
||||||
if (reject->code == PPP_CODE_REJECT) {
|
if (reject.code == PPP_CODE_REJECT) {
|
||||||
uint8 rejectedCode = reject->data[0];
|
uint8 rejectedCode = reject.data[0];
|
||||||
|
|
||||||
// test if the rejected code belongs to the minimum LCP requirements
|
// test if the rejected code belongs to the minimum LCP requirements
|
||||||
if (rejectedCode >= PPP_MIN_LCP_CODE && rejectedCode <= PPP_MAX_LCP_CODE) {
|
if (rejectedCode >= PPP_MIN_LCP_CODE && rejectedCode <= PPP_MAX_LCP_CODE) {
|
||||||
if (Interface().IsMultilink() && !Interface().Parent()) {
|
if (Interface().IsMultilink() && !Interface().Parent()) {
|
||||||
// Main interfaces do not have states between STARTING and OPENED.
|
// Main interfaces do not have states between STARTING and OPENED.
|
||||||
// An RXJBadEvent() would enter one of those states which is bad.
|
// An RXJBadEvent() would enter one of those states which is bad.
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
} else
|
} else
|
||||||
RXJBadEvent(packet);
|
RXJBadEvent(packet);
|
||||||
@@ -1514,10 +1617,10 @@ KPPPStateMachine::RXJEvent(struct mbuf *packet)
|
|||||||
lcpExtension->SetEnabled(false);
|
lcpExtension->SetEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
} else if (reject->code == PPP_PROTOCOL_REJECT) {
|
} else if (reject.code == PPP_PROTOCOL_REJECT) {
|
||||||
// disable all handlers for rejected protocol type
|
// disable all handlers for rejected protocol type
|
||||||
uint16 rejected = *((uint16*) reject->data);
|
uint16 rejected = *((uint16*) reject.data);
|
||||||
// rejected protocol number
|
// rejected protocol number
|
||||||
|
|
||||||
if (rejected == PPP_LCP_PROTOCOL) {
|
if (rejected == PPP_LCP_PROTOCOL) {
|
||||||
@@ -1541,7 +1644,7 @@ KPPPStateMachine::RXJEvent(struct mbuf *packet)
|
|||||||
if (Interface().Parent())
|
if (Interface().Parent())
|
||||||
Interface().Parent()->StateMachine().RXJEvent(packet);
|
Interface().Parent()->StateMachine().RXJEvent(packet);
|
||||||
else
|
else
|
||||||
m_freem(packet);
|
gBufferModule->free(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1552,7 +1655,7 @@ KPPPStateMachine::IllegalEvent(ppp_event event)
|
|||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
// update error statistics
|
// update error statistics
|
||||||
ERROR("KPPPSM: IllegalEvent(event=%d) state=%d phase=%d\n",
|
TRACE("KPPPSM: IllegalEvent(event=%d) state=%d phase=%d\n",
|
||||||
event, State(), Phase());
|
event, State(), Phase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1643,48 +1746,60 @@ KPPPStateMachine::SendConfigureRequest()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LCP().Send(request.ToMbuf(Interface().MRU(),
|
return LCP().Send(request.ToNetBuffer(Interface().MRU())) == B_OK;
|
||||||
LCP().AdditionalOverhead())) == B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
KPPPStateMachine::SendConfigureAck(struct mbuf *packet)
|
KPPPStateMachine::SendConfigureAck(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: SendConfigureAck() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: SendConfigureAck() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mtod(packet, ppp_lcp_packet*)->code = PPP_CONFIGURE_ACK;
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return false;
|
||||||
|
ppp_lcp_packet &header = bufferHeader.Data();
|
||||||
|
|
||||||
|
header.code = PPP_CONFIGURE_ACK;
|
||||||
|
bufferHeader.Sync();
|
||||||
|
|
||||||
KPPPConfigurePacket ack(packet);
|
KPPPConfigurePacket ack(packet);
|
||||||
|
|
||||||
// notify all option handlers that we are sending an ack for each value
|
// notify all option handlers that we are sending an ack for each value
|
||||||
for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||||
if (LCP().OptionHandlerAt(index)->SendingAck(ack) != B_OK) {
|
if (LCP().OptionHandlerAt(index)->SendingAck(ack) != B_OK) {
|
||||||
m_freem(packet);
|
TRACE("%s::%s: SendingAck %ld fail\n", __FILE__, __func__, index);
|
||||||
|
gBufferModule->free(packet);
|
||||||
CloseEvent();
|
CloseEvent();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRACE("%s::%s: LCP().Send\n", __FILE__, __func__);
|
||||||
return LCP().Send(packet) == B_OK;
|
return LCP().Send(packet) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
KPPPStateMachine::SendConfigureNak(struct mbuf *packet)
|
KPPPStateMachine::SendConfigureNak(net_buffer *packet)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: SendConfigureNak() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: SendConfigureNak() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
if (nak->code == PPP_CONFIGURE_NAK) {
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return false;
|
||||||
|
ppp_lcp_packet &nak = bufferHeader.Data();
|
||||||
|
|
||||||
|
if (nak.code == PPP_CONFIGURE_NAK) {
|
||||||
if (fNakCounter == 0) {
|
if (fNakCounter == 0) {
|
||||||
// We sent enough naks. Let's try a reject.
|
// We sent enough naks. Let's try a reject.
|
||||||
nak->code = PPP_CONFIGURE_REJECT;
|
nak.code = PPP_CONFIGURE_REJECT;
|
||||||
} else
|
} else
|
||||||
--fNakCounter;
|
--fNakCounter;
|
||||||
}
|
}
|
||||||
@@ -1701,55 +1816,60 @@ KPPPStateMachine::SendTerminateRequest()
|
|||||||
--fTerminateCounter;
|
--fTerminateCounter;
|
||||||
fNextTimeout = system_time() + kPPPStateMachineTimeout;
|
fNextTimeout = system_time() + kPPPStateMachineTimeout;
|
||||||
|
|
||||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
net_buffer *buffer = gBufferModule->create(256);
|
||||||
|
if (buffer == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ppp_lcp_packet *packet;
|
||||||
|
status_t status = gBufferModule->append_size(buffer, 1492, (void **)&packet);
|
||||||
|
if (status == B_OK && packet == NULL) {
|
||||||
|
gBufferModule->free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
packet->m_pkthdr.len = packet->m_len = 4;
|
packet->code = PPP_TERMINATE_REQUEST;
|
||||||
|
packet->id = fTerminateID = NextID();
|
||||||
|
packet->length = htons(4);
|
||||||
|
|
||||||
// reserve some space for other protocols
|
status = gBufferModule->trim(buffer, 4);
|
||||||
packet->m_data += LCP().AdditionalOverhead();
|
if (status < B_OK) {
|
||||||
|
gBufferModule->free(buffer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
return LCP().Send(buffer) == B_OK;
|
||||||
request->code = PPP_TERMINATE_REQUEST;
|
|
||||||
request->id = fTerminateID = NextID();
|
|
||||||
request->length = htons(4);
|
|
||||||
|
|
||||||
return LCP().Send(packet) == B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
KPPPStateMachine::SendTerminateAck(struct mbuf *request)
|
KPPPStateMachine::SendTerminateAck(net_buffer *request)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: SendTerminateAck() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: SendTerminateAck() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
struct mbuf *reply = request;
|
net_buffer *reply = request;
|
||||||
|
|
||||||
ppp_lcp_packet *ack;
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(request);
|
||||||
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return false;
|
||||||
|
ppp_lcp_packet &ack = bufferHeader.Data();
|
||||||
|
|
||||||
if (!reply) {
|
if (!reply) {
|
||||||
reply = m_gethdr(MT_DATA);
|
ack.length = htons(4);
|
||||||
if (!reply)
|
ack.id = NextID();
|
||||||
return false;
|
}
|
||||||
|
|
||||||
reply->m_data += LCP().AdditionalOverhead();
|
ack.code = PPP_TERMINATE_ACK;
|
||||||
reply->m_pkthdr.len = reply->m_len = 4;
|
ack.length = htons(4);
|
||||||
|
|
||||||
ack = mtod(reply, ppp_lcp_packet*);
|
|
||||||
ack->id = NextID();
|
|
||||||
} else
|
|
||||||
ack = mtod(reply, ppp_lcp_packet*);
|
|
||||||
|
|
||||||
ack->code = PPP_TERMINATE_ACK;
|
|
||||||
ack->length = htons(4);
|
|
||||||
|
|
||||||
return LCP().Send(reply) == B_OK;
|
return LCP().Send(reply) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
KPPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code)
|
KPPPStateMachine::SendCodeReject(net_buffer *packet, uint16 protocolNumber, uint8 code)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: SendCodeReject(protocolNumber=%X;code=%d) state=%d phase=%d\n",
|
TRACE("KPPPSM: SendCodeReject(protocolNumber=%X;code=%d) state=%d phase=%d\n",
|
||||||
protocolNumber, code, State(), Phase());
|
protocolNumber, code, State(), Phase());
|
||||||
@@ -1764,52 +1884,40 @@ KPPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uin
|
|||||||
else
|
else
|
||||||
length = 4;
|
length = 4;
|
||||||
|
|
||||||
M_PREPEND(packet, length);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||||
// add some space for the header
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return false;
|
||||||
|
ppp_lcp_packet &reject = bufferHeader.Data();
|
||||||
|
|
||||||
// adjust packet if too big
|
reject.code = code;
|
||||||
int32 adjust = Interface().MRU();
|
reject.id = NextID();
|
||||||
if (packet->m_flags & M_PKTHDR) {
|
reject.length = htons(length);
|
||||||
adjust -= packet->m_pkthdr.len;
|
|
||||||
} else
|
|
||||||
adjust -= packet->m_len;
|
|
||||||
|
|
||||||
if (adjust < 0)
|
|
||||||
m_adj(packet, adjust);
|
|
||||||
|
|
||||||
ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
|
|
||||||
reject->code = code;
|
|
||||||
reject->id = NextID();
|
|
||||||
if (packet->m_flags & M_PKTHDR)
|
|
||||||
reject->length = htons(packet->m_pkthdr.len);
|
|
||||||
else
|
|
||||||
reject->length = htons(packet->m_len);
|
|
||||||
|
|
||||||
protocolNumber = htons(protocolNumber);
|
protocolNumber = htons(protocolNumber);
|
||||||
if (code == PPP_PROTOCOL_REJECT)
|
if (code == PPP_PROTOCOL_REJECT)
|
||||||
memcpy(&reject->data, &protocolNumber, sizeof(protocolNumber));
|
memcpy(&reject.data, &protocolNumber, sizeof(protocolNumber));
|
||||||
|
|
||||||
return LCP().Send(packet) == B_OK;
|
return LCP().Send(packet) == B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
KPPPStateMachine::SendEchoReply(struct mbuf *request)
|
KPPPStateMachine::SendEchoReply(net_buffer *request)
|
||||||
{
|
{
|
||||||
TRACE("KPPPSM: SendEchoReply() state=%d phase=%d\n", State(), Phase());
|
TRACE("KPPPSM: SendEchoReply() state=%d phase=%d\n", State(), Phase());
|
||||||
|
|
||||||
if (!request)
|
if (!request)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ppp_lcp_packet *reply = mtod(request, ppp_lcp_packet*);
|
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(request);
|
||||||
reply->code = PPP_ECHO_REPLY;
|
if (bufferHeader.Status() < B_OK)
|
||||||
|
return false;
|
||||||
|
ppp_lcp_packet &reply = bufferHeader.Data();
|
||||||
|
|
||||||
|
reply.code = PPP_ECHO_REPLY;
|
||||||
// the request becomes a reply
|
// the request becomes a reply
|
||||||
|
|
||||||
if (request->m_flags & M_PKTHDR)
|
memcpy(reply.data, &fMagicNumber, sizeof(fMagicNumber));
|
||||||
request->m_pkthdr.len = 8;
|
|
||||||
request->m_len = 8;
|
|
||||||
|
|
||||||
memcpy(reply->data, &fMagicNumber, sizeof(fMagicNumber));
|
|
||||||
|
|
||||||
return LCP().Send(request) == B_OK;
|
return LCP().Send(request) == B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,7 +83,7 @@ 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;
|
||||||
@@ -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;
|
||||||
@@ -116,22 +117,22 @@ class KPPPStateMachine {
|
|||||||
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);
|
||||||
@@ -142,12 +143,12 @@ 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();
|
||||||
@@ -162,7 +163,7 @@ class KPPPStateMachine {
|
|||||||
ppp_state fState;
|
ppp_state fState;
|
||||||
ppp_phase fPhase;
|
ppp_phase fPhase;
|
||||||
|
|
||||||
vint32 fID;
|
int32 fID;
|
||||||
uint32 fMagicNumber;
|
uint32 fMagicNumber;
|
||||||
int32 fLastConnectionReportCode;
|
int32 fLastConnectionReportCode;
|
||||||
|
|
||||||
@@ -177,7 +178,7 @@ class KPPPStateMachine {
|
|||||||
// 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;
|
||||||
|
|
||||||
@@ -251,8 +383,23 @@ 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;
|
||||||
@@ -269,8 +416,23 @@ 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 (Control(PPPC_CREATE_INTERFACE_WITH_NAME, &info, sizeof(info)) != B_OK)
|
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 PPP_UNDEFINED_INTERFACE_ID;
|
||||||
else
|
}
|
||||||
return info.interface;
|
|
||||||
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -253,14 +347,18 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -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
|
|
||||||
@@ -40,6 +40,12 @@ class PPPInterface {
|
|||||||
bool GetStatistics(ppp_statistics *statistics) const;
|
bool GetStatistics(ppp_statistics *statistics) const;
|
||||||
bool HasSettings(const driver_settings *settings) const;
|
bool HasSettings(const driver_settings *settings) const;
|
||||||
|
|
||||||
|
bool ControlDevice(ppp_device_info_t *info) const;
|
||||||
|
bool ControlProtocol(ppp_protocol_info_t *info, uint32 protocolindex, uint32 procotolOP) const;
|
||||||
|
bool ControlOptionHandler(ppp_simple_handler_info_t *info, uint32 handlerindex, uint32 handlerOP) const;
|
||||||
|
bool ControlLCPExtension(ppp_simple_handler_info_t *info, uint32 LCPExtensionindex, uint32 LCPExtensionOP) const;
|
||||||
|
bool ControlChild(void *info, uint32 childindex, uint32 childOP) const;
|
||||||
|
|
||||||
bool Up() const;
|
bool Up() const;
|
||||||
bool Down() const;
|
bool Down() const;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#ifndef _PPP_MANAGER__H
|
#ifndef _PPP_MANAGER__H
|
||||||
#define _PPP_MANAGER__H
|
#define _PPP_MANAGER__H
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
#include <KPPPManager.h>
|
#include <KPPPManager.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ class PPPManager {
|
|||||||
ppp_interface_id CreateInterface(const driver_settings *settings) const;
|
ppp_interface_id CreateInterface(const driver_settings *settings) const;
|
||||||
ppp_interface_id CreateInterfaceWithName(const char *name) const;
|
ppp_interface_id CreateInterfaceWithName(const char *name) const;
|
||||||
bool DeleteInterface(ppp_interface_id ID) const;
|
bool DeleteInterface(ppp_interface_id ID) const;
|
||||||
|
bool DeleteInterface(const char* name) const;
|
||||||
|
|
||||||
ppp_interface_id *Interfaces(int32 *count,
|
ppp_interface_id *Interfaces(int32 *count,
|
||||||
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const;
|
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const;
|
||||||
|
|||||||
@@ -833,6 +833,9 @@ init_stack()
|
|||||||
// TODO: for now!
|
// TODO: for now!
|
||||||
register_domain_datalink_protocols(AF_INET, IFT_LOOP,
|
register_domain_datalink_protocols(AF_INET, IFT_LOOP,
|
||||||
"network/datalink_protocols/loopback_frame/v1", NULL);
|
"network/datalink_protocols/loopback_frame/v1", NULL);
|
||||||
|
// add ppp datalink protocol
|
||||||
|
register_domain_datalink_protocols(AF_INET, IFT_PPP,
|
||||||
|
"network/datalink_protocols/ppp_frame/v1", NULL);
|
||||||
register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
|
register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
|
||||||
"network/datalink_protocols/loopback_frame/v1", NULL);
|
"network/datalink_protocols/loopback_frame/v1", NULL);
|
||||||
register_domain_datalink_protocols(AF_INET, IFT_ETHER,
|
register_domain_datalink_protocols(AF_INET, IFT_ETHER,
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ SubInclude HAIKU_TOP src bin network ftpd ;
|
|||||||
SubInclude HAIKU_TOP src bin network ifconfig ;
|
SubInclude HAIKU_TOP src bin network ifconfig ;
|
||||||
SubInclude HAIKU_TOP src bin network mount_nfs ;
|
SubInclude HAIKU_TOP src bin network mount_nfs ;
|
||||||
SubInclude HAIKU_TOP src bin network netstat ;
|
SubInclude HAIKU_TOP src bin network netstat ;
|
||||||
#SubInclude HAIKU_TOP src bin network pppconfig ;
|
SubInclude HAIKU_TOP src bin network pppconfig ;
|
||||||
#SubInclude HAIKU_TOP src bin network ppp_up ;
|
SubInclude HAIKU_TOP src bin network ppp_up ;
|
||||||
SubInclude HAIKU_TOP src bin network ping ;
|
SubInclude HAIKU_TOP src bin network ping ;
|
||||||
SubInclude HAIKU_TOP src bin network ping6 ;
|
SubInclude HAIKU_TOP src bin network ping6 ;
|
||||||
SubInclude HAIKU_TOP src bin network route ;
|
SubInclude HAIKU_TOP src bin network route ;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
SubDir HAIKU_TOP src bin ppp_up ;
|
SubDir HAIKU_TOP src bin network ppp_up ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
||||||
|
|
||||||
@@ -8,7 +8,10 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
UsePrivateHeaders net ;
|
UsePrivateKernelHeaders ;
|
||||||
|
UsePrivateHeaders net app libroot shared interface libbe be root tracker textencoding
|
||||||
|
root ;
|
||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||||
headers ] : true ;
|
headers ] : true ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||||
@@ -24,7 +27,7 @@ BinCommand ppp_up :
|
|||||||
PPPStatusWindow.cpp
|
PPPStatusWindow.cpp
|
||||||
PPPUpApplication.cpp
|
PPPUpApplication.cpp
|
||||||
:
|
:
|
||||||
libppp.a be
|
libppp.a be $(TARGET_LIBSUPC++) translation $(HAIKU_LOCALE_LIBS) root $(TARGET_NETWORK_LIBS)
|
||||||
;
|
;
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
#ifndef STATUS_VIEW__H
|
#ifndef STATUS_VIEW__H
|
||||||
#define STATUS_VIEW__H
|
#define STATUS_VIEW__H
|
||||||
|
|
||||||
#include <View.h>
|
#include <Button.h>
|
||||||
#include <PPPInterface.h>
|
#include <PPPInterface.h>
|
||||||
|
#include <StringView.h>
|
||||||
|
|
||||||
|
|
||||||
class PPPStatusView : public BView {
|
class PPPStatusView : public BView {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
SubDir HAIKU_TOP src bin pppconfig ;
|
SubDir HAIKU_TOP src bin network pppconfig ;
|
||||||
|
|
||||||
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
|||||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||||
headers ] : true ;
|
headers ] : true ;
|
||||||
@@ -17,7 +18,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
|||||||
BinCommand pppconfig :
|
BinCommand pppconfig :
|
||||||
pppconfig.cpp
|
pppconfig.cpp
|
||||||
:
|
:
|
||||||
be libppp.a
|
be libppp.a $(TARGET_LIBSUPC++) $(TARGET_NETWORK_LIBS)
|
||||||
;
|
;
|
||||||
|
|
||||||
# Installation -- in the test directory for the time being
|
# Installation -- in the test directory for the time being
|
||||||
|
|||||||
@@ -45,14 +45,16 @@ show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
|||||||
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;
|
||||||
|
|
||||||
@@ -179,6 +181,417 @@ connect(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
setuser(const char *name, const char* user)
|
||||||
|
{
|
||||||
|
if (!name || strlen(name) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!user || strlen(user) == 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.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
|
static
|
||||||
status_t
|
status_t
|
||||||
disconnect(const char *name)
|
disconnect(const char *name)
|
||||||
@@ -220,7 +633,7 @@ delete_interface(const char *name)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@@ -242,13 +655,20 @@ show_details(const char *name)
|
|||||||
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)
|
||||||
@@ -328,6 +748,33 @@ main(int argc, char *argv[])
|
|||||||
return delete_interface(argv[2]);
|
return delete_interface(argv[2]);
|
||||||
else if (!strcmp(argv[1], "details"))
|
else if (!strcmp(argv[1], "details"))
|
||||||
return show_details(argv[2]);
|
return show_details(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "getstatistics"))
|
||||||
|
return getstatistics(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "hassettings"))
|
||||||
|
return hassettings(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "enablereports"))
|
||||||
|
return enablereports(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "disablereports"))
|
||||||
|
return disablereports(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controldevice"))
|
||||||
|
return controldevice(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controlprotocol"))
|
||||||
|
return controlprotocol(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controloptionhandler"))
|
||||||
|
return controloptionhandler(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controllcpextension"))
|
||||||
|
return controllcpextension(argv[2]);
|
||||||
|
else if (!strcmp(argv[1], "controlchild"))
|
||||||
|
return controlchild(argv[2]);
|
||||||
|
else
|
||||||
|
return print_help();
|
||||||
|
} if (argc == 4) {
|
||||||
|
if (!strcmp(argv[1], "setuser"))
|
||||||
|
return setuser(argv[2], argv[3]);
|
||||||
|
else if (!strcmp(argv[1], "setpass"))
|
||||||
|
return setpass(argv[2], argv[3]);
|
||||||
|
else if (!strcmp(argv[1], "setaskbeforeconnect"))
|
||||||
|
return setaskbeforeconnect(argv[2], argv[3]);
|
||||||
else
|
else
|
||||||
return print_help();
|
return print_help();
|
||||||
} else
|
} else
|
||||||
|
|||||||
Reference in New Issue
Block a user