PPP: Port to the new stack.
Signed-off-by: Augustin Cavalier <[email protected]> This is a squash of the 42 commits by @mshlyn, as I couldn't find a way to break them into logical chunks. I did not include these in the build, as it appears that they only partially work anyway, and much more cleanup is still needed. However, this is a huge improvement on what was in the tree before, which looked horrendous and didn't even compile (as it was designed for the old stack). Mostly fixes #812.
This commit is contained in:
committed by
Augustin Cavalier
parent
7121057cb7
commit
e3724c38cb
@@ -134,7 +134,7 @@ SYSTEM_NETWORK_DATALINK_PROTOCOLS =
|
||||
loopback_frame
|
||||
;
|
||||
|
||||
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe ;
|
||||
#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe KPPPManager ;
|
||||
|
||||
SYSTEM_NETWORK_PROTOCOLS =
|
||||
icmp icmp6 ipv4 ipv6
|
||||
|
||||
@@ -6,3 +6,4 @@ SubInclude HAIKU_TOP src add-ons kernel network dns_resolver ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network notifications ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network protocols ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network stack ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp ;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
|
||||
# SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp pap ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp shared ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
|
||||
|
||||
@@ -1,41 +1,51 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp ipcp ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||
# Needed for the atomic_add64() prototype.
|
||||
}
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
# for kernel_cpp.h and BLocker
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
UsePrivateHeaders libroot net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
|
||||
{
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
}
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp pppoe
|
||||
] : true ;
|
||||
|
||||
KernelAddon ipcp :
|
||||
# imported from libnet
|
||||
atomic.S
|
||||
kernel_cpp.cpp
|
||||
|
||||
# imported from kernel util
|
||||
inet_addr.c
|
||||
|
||||
ipcp.cpp
|
||||
Protocol.cpp
|
||||
;
|
||||
|
||||
|
||||
SEARCH on [ FGristFiles inet_addr.c ]
|
||||
= [ FDirName $(HAIKU_TOP) src kits network compat libnet ] ;
|
||||
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||
|
||||
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||
SEARCH on [ FGristFiles atomic.S ]
|
||||
= [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
|
||||
|
||||
LinkAgainst ipcp : libkernelppp.a ;
|
||||
|
||||
# Installation
|
||||
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
||||
: /boot/home/config/add-ons/kernel/network/ppp
|
||||
: ipcp ;
|
||||
|
||||
@@ -13,11 +13,29 @@
|
||||
#include <KPPPInterface.h>
|
||||
#include <settings_tools.h>
|
||||
|
||||
#include <PPPoEDevice.h>
|
||||
|
||||
#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>
|
||||
|
||||
// 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
|
||||
#include <unistd.h>
|
||||
@@ -26,7 +44,7 @@ static int sFD;
|
||||
// the file descriptor for debug output
|
||||
static char sDigits[] = "0123456789ABCDEF";
|
||||
void
|
||||
dump_packet(struct mbuf *packet, const char *direction)
|
||||
dump_packet(net_buffer *packet, const char *direction)
|
||||
{
|
||||
if (!packet)
|
||||
return;
|
||||
@@ -87,6 +105,8 @@ IPCP::IPCP(KPPPInterface& interface, driver_parameter *settings)
|
||||
ParseSideRequests(get_parameter_with_name(IPCP_PEER_SIDE_KEY, Settings()),
|
||||
PPP_PEER_SIDE);
|
||||
|
||||
get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule);
|
||||
get_module(NET_DATALINK_MODULE_NAME, (module_info **)&sDatalinkModule);
|
||||
#if DEBUG
|
||||
sFD = open("/boot/home/ipcpdebug", O_WRONLY | O_CREAT | O_TRUNC);
|
||||
#endif
|
||||
@@ -95,6 +115,9 @@ IPCP::IPCP(KPPPInterface& interface, driver_parameter *settings)
|
||||
|
||||
IPCP::~IPCP()
|
||||
{
|
||||
|
||||
put_module(NET_DATALINK_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
#if DEBUG
|
||||
close(sFD);
|
||||
#endif
|
||||
@@ -205,7 +228,7 @@ IPCP::Down()
|
||||
|
||||
|
||||
status_t
|
||||
IPCP::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
IPCP::Send(net_buffer *packet, uint16 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");
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
IPCP::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
TRACE("IPCP: Receive(0x%X)\n", protocolNumber);
|
||||
|
||||
@@ -239,21 +262,16 @@ IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
if (protocolNumber != IPCP_PROTOCOL)
|
||||
return PPP_UNHANDLED;
|
||||
|
||||
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return B_ERROR;
|
||||
ppp_lcp_packet &data = bufferheader.Data();
|
||||
|
||||
// remove padding
|
||||
int32 length = packet->m_len;
|
||||
if(packet->m_flags & M_PKTHDR)
|
||||
length = packet->m_pkthdr.len;
|
||||
length -= ntohs(data->length);
|
||||
if(length)
|
||||
m_adj(packet, -length);
|
||||
|
||||
if(ntohs(data->length) < 4)
|
||||
if (ntohs(data.length) < 4)
|
||||
return B_ERROR;
|
||||
|
||||
// packet is freed by event methods
|
||||
switch(data->code) {
|
||||
switch (data.code) {
|
||||
case PPP_CONFIGURE_REQUEST:
|
||||
RCREvent(packet);
|
||||
break;
|
||||
@@ -290,23 +308,26 @@ IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
|
||||
|
||||
status_t
|
||||
IPCP::ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber)
|
||||
IPCP::ReceiveIPPacket(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
if (protocolNumber != IP_PROTOCOL || State() != PPP_OPENED_STATE)
|
||||
return PPP_UNHANDLED;
|
||||
|
||||
// TODO: add VJC support (the packet would be decoded here)
|
||||
|
||||
if (gProto[IPPROTO_IP] && gProto[IPPROTO_IP]->pr_input) {
|
||||
if (packet)
|
||||
{
|
||||
#if DEBUG
|
||||
dump_packet(packet, "incoming");
|
||||
#endif
|
||||
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;
|
||||
} else {
|
||||
ERROR("IPCP: Error: Could not find input function for IP!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
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
|
||||
if (strcasecmp(requests->parameters[index].values[0], "auto")) {
|
||||
address = inet_addr(requests->parameters[index].values[0]);
|
||||
// address = INADDR_ANY;
|
||||
if (address == INADDR_NONE)
|
||||
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
|
||||
IPCP::UpdateAddresses()
|
||||
{
|
||||
TRACE("%s::%s: entering UpdateAddresses\n", __FILE__, __func__);
|
||||
RemoveRoutes();
|
||||
|
||||
if (State() != PPP_OPENED_STATE && !Interface().DoesConnectOnDemand())
|
||||
return;
|
||||
|
||||
struct in_aliasreq inreq;
|
||||
struct ifreq ifreqAddress, ifreqDestination;
|
||||
memset(&inreq, 0, sizeof(struct in_aliasreq));
|
||||
memset(&ifreqAddress, 0, sizeof(struct ifreq));
|
||||
memset(&ifreqDestination, 0, sizeof(struct ifreq));
|
||||
memset(&fGateway, 0, sizeof(struct sockaddr_in));
|
||||
TRACE("%s::%s: entering ChangeAddress\n", __FILE__, __func__);
|
||||
if (sDatalinkModule == NULL) {
|
||||
TRACE("%s::%s: some module not found!\n", __FILE__, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
inreq.ifra_addr.sin_addr.s_addr = fLocalRequests.address;
|
||||
else if(fLocalConfiguration.address == INADDR_ANY)
|
||||
inreq.ifra_addr.sin_addr.s_addr = 0x010F0F0F; // was: INADDR_BROADCAST
|
||||
else
|
||||
inreq.ifra_addr.sin_addr.s_addr = fLocalConfiguration.address;
|
||||
inreq.ifra_addr.sin_len = sizeof(struct sockaddr_in);
|
||||
memcpy(&ifreqAddress.ifr_addr, &inreq.ifra_addr, sizeof(struct sockaddr_in));
|
||||
memcpy(newAddr.sa_data + 2, &fLocalRequests.address, sizeof(in_addr_t));
|
||||
else if (fLocalConfiguration.address == INADDR_ANY) {
|
||||
in_addr_t inaddrBroadcast = 0x010F0F0F; // was: INADDR_BROADCAST
|
||||
memcpy(newAddr.sa_data + 2, &inaddrBroadcast, sizeof(in_addr_t));
|
||||
} else
|
||||
memcpy(newAddr.sa_data + 2, &fLocalConfiguration.address, sizeof(in_addr_t));
|
||||
|
||||
// create destination address
|
||||
fGateway.sin_family = AF_INET;
|
||||
if(fPeerRequests.address != INADDR_ANY)
|
||||
fGateway.sin_addr.s_addr = fPeerRequests.address;
|
||||
else if(fPeerConfiguration.address == INADDR_ANY)
|
||||
fGateway.sin_addr.s_addr = 0x020F0F0F; // was: INADDR_BROADCAST
|
||||
else
|
||||
fGateway.sin_addr.s_addr = fPeerConfiguration.address;
|
||||
fGateway.sin_len = sizeof(struct sockaddr_in);
|
||||
memcpy(&inreq.ifra_dstaddr, &fGateway,
|
||||
sizeof(struct sockaddr_in));
|
||||
memcpy(&ifreqDestination.ifr_dstaddr, &inreq.ifra_dstaddr,
|
||||
sizeof(struct sockaddr_in));
|
||||
struct ifaliasreq inreq;
|
||||
memset(&inreq, 0, sizeof(struct ifaliasreq));
|
||||
memcpy(inreq.ifra_name, Interface().Name(), IF_NAMESIZE);
|
||||
memcpy(&inreq.ifra_addr, &newAddr, sizeof(struct sockaddr));
|
||||
memcpy(&inreq.ifra_mask, &netmask, sizeof(struct sockaddr));
|
||||
memcpy(&inreq.ifra_broadaddr, &broadaddr, sizeof(struct sockaddr));
|
||||
inreq.ifra_index = -1;
|
||||
// create a new interface address
|
||||
// Is it OK when we already have one?
|
||||
// test case: ifconfig ppp up
|
||||
// ifconfig ppp down
|
||||
// ifconfig ppp up
|
||||
// check if some weird things happen
|
||||
|
||||
// create netmask
|
||||
inreq.ifra_mask.sin_family = AF_INET;
|
||||
inreq.ifra_mask.sin_addr.s_addr = fLocalRequests.netmask;
|
||||
inreq.ifra_mask.sin_len = sizeof(struct sockaddr_in);
|
||||
net_domain* domain = sStackModule->get_domain(AF_INET);
|
||||
status_t status = set_interface_address(domain, &inreq);
|
||||
|
||||
// tell stack to use these values
|
||||
if(in_control(NULL, SIOCAIFADDR, (caddr_t) &inreq,
|
||||
Interface().Ifnet()) != B_OK)
|
||||
ERROR("IPCP: UpdateAddress(): SIOCAIFADDR returned error!\n");
|
||||
if(in_control(NULL, SIOCSIFADDR, (caddr_t) &ifreqAddress,
|
||||
Interface().Ifnet()) != B_OK)
|
||||
ERROR("IPCP: UpdateAddress(): SIOCSIFADDR returned error!\n");
|
||||
if(in_control(NULL, SIOCSIFDSTADDR, (caddr_t) &ifreqDestination,
|
||||
Interface().Ifnet()) != B_OK)
|
||||
ERROR("IPCP: UpdateAddress(): SIOCSIFDSTADDR returned error!\n");
|
||||
memcpy(&inreq.ifra_addr, &inreq.ifra_mask, sizeof(struct sockaddr_in));
|
||||
// SIOCISFNETMASK wants the netmask to be in ifra_addr
|
||||
if(in_control(NULL, SIOCSIFNETMASK, (caddr_t) &inreq,
|
||||
Interface().Ifnet()) != B_OK)
|
||||
ERROR("IPCP: UpdateAddress(): SIOCSIFNETMASK returned error!\n");
|
||||
if (status != B_OK) {
|
||||
TRACE("%s:%s: set_interface_address Fail!!!!\n", __FILE__, __func__);
|
||||
return;
|
||||
}
|
||||
TRACE("%s:%s: set_interface_address fine\n", __FILE__, __func__);
|
||||
|
||||
|
||||
net_interface* pppInterface = get_interface_by_name(domain, Interface().Name());
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
// add default/subnet route
|
||||
if(Side() == PPP_LOCAL_SIDE) {
|
||||
if(rtrequest(RTM_ADD, (struct sockaddr*) &inreq.ifra_mask,
|
||||
(struct sockaddr*) &fGateway, (struct sockaddr*) &inreq.ifra_mask,
|
||||
RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK)
|
||||
ERROR("IPCP: UpdateAddress(): could not add default/subnet route!\n");
|
||||
if (Side() == PPP_LOCAL_SIDE && pppInterfaceAddress != NULL) {
|
||||
struct sockaddr addrGateway = {8, AF_INET, {0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00} };
|
||||
|
||||
--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
|
||||
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) {
|
||||
struct sockaddr_in netmask;
|
||||
@@ -484,9 +636,9 @@ IPCP::RemoveRoutes()
|
||||
netmask.sin_addr.s_addr = fLocalRequests.netmask;
|
||||
netmask.sin_len = sizeof(struct sockaddr_in);
|
||||
|
||||
if(rtrequest(RTM_DELETE, (struct sockaddr*) &netmask,
|
||||
(struct sockaddr*) &fGateway, (struct sockaddr*) &netmask,
|
||||
RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK)
|
||||
// if (rtrequest(RTM_DELETE, (struct sockaddr*) &netmask,
|
||||
// (struct sockaddr*) &fGateway, (struct sockaddr*) &netmask,
|
||||
// RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK)
|
||||
ERROR("IPCP: RemoveRoutes(): could not remove default/subnet route!\n");
|
||||
|
||||
fDefaultRoute = NULL;
|
||||
@@ -571,7 +723,7 @@ IPCP::TOBadEvent()
|
||||
|
||||
|
||||
void
|
||||
IPCP::RCREvent(struct mbuf *packet)
|
||||
IPCP::RCREvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("IPCP: RCREvent() state=%d\n", State());
|
||||
|
||||
@@ -579,8 +731,13 @@ IPCP::RCREvent(struct mbuf *packet)
|
||||
KPPPConfigurePacket nak(PPP_CONFIGURE_NAK);
|
||||
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
|
||||
if(fID == mtod(packet, ppp_lcp_packet*)->id)
|
||||
if (fID == lcpHeader.id)
|
||||
fID -= 128;
|
||||
|
||||
nak.SetID(request.ID());
|
||||
@@ -620,7 +777,7 @@ IPCP::RCREvent(struct mbuf *packet)
|
||||
case IPCP_SECONDARY_DNS:
|
||||
if (item->length != 6) {
|
||||
// the packet is invalid
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
NewState(PPP_INITIAL_STATE);
|
||||
ReportUpFailedEvent();
|
||||
return;
|
||||
@@ -630,7 +787,7 @@ IPCP::RCREvent(struct mbuf *packet)
|
||||
if (*wishedAddress == INADDR_ANY) {
|
||||
if (*requestedAddress == INADDR_ANY) {
|
||||
// we do not have an address for you
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
NewState(PPP_INITIAL_STATE);
|
||||
ReportUpFailedEvent();
|
||||
return;
|
||||
@@ -665,19 +822,18 @@ IPCP::RCREvent(struct mbuf *packet)
|
||||
}
|
||||
|
||||
if (nak.CountItems() > 0) {
|
||||
RCRBadEvent(nak.ToMbuf(Interface().MRU(), Interface().PacketOverhead()), NULL);
|
||||
m_freem(packet);
|
||||
RCRBadEvent(nak.ToNetBuffer(Interface().MRU()), NULL);
|
||||
gBufferModule->free(packet);
|
||||
} else if (reject.CountItems() > 0) {
|
||||
RCRBadEvent(NULL, reject.ToMbuf(Interface().MRU(),
|
||||
Interface().PacketOverhead()));
|
||||
m_freem(packet);
|
||||
RCRBadEvent(NULL, reject.ToNetBuffer(Interface().MRU()));
|
||||
gBufferModule->free(packet);
|
||||
} else
|
||||
RCRGoodEvent(packet);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IPCP::RCRGoodEvent(struct mbuf *packet)
|
||||
IPCP::RCRGoodEvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("IPCP: RCRGoodEvent() state=%d\n", State());
|
||||
|
||||
@@ -709,16 +865,36 @@ IPCP::RCRGoodEvent(struct mbuf *packet)
|
||||
break;
|
||||
|
||||
default:
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IPCP::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
||||
IPCP::RCRBadEvent(net_buffer *nak, net_buffer *reject)
|
||||
{
|
||||
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()) {
|
||||
case PPP_OPENED_STATE:
|
||||
NewState(PPP_REQ_SENT_STATE);
|
||||
@@ -732,9 +908,9 @@ IPCP::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
||||
case PPP_INITIAL_STATE:
|
||||
case PPP_REQ_SENT_STATE:
|
||||
case PPP_ACK_RCVD_STATE:
|
||||
if(nak && ntohs(mtod(nak, ppp_lcp_packet*)->length) > 3)
|
||||
if (nak && ntohs(lcpHdrNakLength) > 3)
|
||||
SendConfigureNak(nak);
|
||||
else if(reject && ntohs(mtod(reject, ppp_lcp_packet*)->length) > 3)
|
||||
else if (reject && ntohs(lcpHdrRejectLength) > 3)
|
||||
SendConfigureNak(reject);
|
||||
return;
|
||||
// prevents the nak/reject from being m_freem()'d
|
||||
@@ -744,22 +920,26 @@ IPCP::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
||||
}
|
||||
|
||||
if (nak)
|
||||
m_freem(nak);
|
||||
gBufferModule->free(nak);
|
||||
if (reject)
|
||||
m_freem(reject);
|
||||
gBufferModule->free(reject);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
// TODO: log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -849,20 +1029,25 @@ IPCP::RCAEvent(struct mbuf *packet)
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IPCP::RCNEvent(struct mbuf *packet)
|
||||
IPCP::RCNEvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
|
||||
// TODO: log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -935,7 +1120,7 @@ IPCP::RCNEvent(struct mbuf *packet)
|
||||
|
||||
default:
|
||||
// DNS and addresses must be supported if we set them to auto
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
NewState(PPP_INITIAL_STATE);
|
||||
ReportUpFailedEvent();
|
||||
return;
|
||||
@@ -962,17 +1147,22 @@ IPCP::RCNEvent(struct mbuf *packet)
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IPCP::RTREvent(struct mbuf *packet)
|
||||
IPCP::RTREvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
if(fID == mtod(packet, ppp_lcp_packet*)->id)
|
||||
if (fID == lcpHeader.id)
|
||||
fID -= 128;
|
||||
|
||||
switch (State()) {
|
||||
@@ -988,33 +1178,37 @@ IPCP::RTREvent(struct mbuf *packet)
|
||||
case PPP_REQ_SENT_STATE:
|
||||
SendTerminateAck(packet);
|
||||
return;
|
||||
// do not m_freem() packet
|
||||
// do not free packet
|
||||
|
||||
case PPP_OPENED_STATE:
|
||||
NewState(PPP_CLOSING_STATE);
|
||||
ResetRestartCount();
|
||||
SendTerminateAck(packet);
|
||||
return;
|
||||
// do not m_freem() packet
|
||||
// do not free packet
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IPCP::RTAEvent(struct mbuf *packet)
|
||||
IPCP::RTAEvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
|
||||
// TODO: log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1041,12 +1235,12 @@ IPCP::RTAEvent(struct mbuf *packet)
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IPCP::RUCEvent(struct mbuf *packet)
|
||||
IPCP::RUCEvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("IPCP: RUCEvent() state=%d\n", State());
|
||||
|
||||
@@ -1055,7 +1249,7 @@ IPCP::RUCEvent(struct mbuf *packet)
|
||||
|
||||
|
||||
void
|
||||
IPCP::RXJBadEvent(struct mbuf *packet)
|
||||
IPCP::RXJBadEvent(net_buffer *packet)
|
||||
{
|
||||
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(&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();
|
||||
}
|
||||
@@ -1169,12 +1365,12 @@ IPCP::SendConfigureRequest()
|
||||
// add address
|
||||
ipItem.type = IPCP_ADDRESS;
|
||||
if (fLocalRequests.address == INADDR_ANY)
|
||||
ipItem.address = fLocalConfiguration.address;
|
||||
ipItem.address = (fLocalConfiguration.address);
|
||||
else
|
||||
ipItem.address = fLocalRequests.address;
|
||||
ipItem.address =(fLocalRequests.address);
|
||||
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,
|
||||
((ip_item*)request.ItemAt(0))->address);
|
||||
|
||||
@@ -1196,20 +1392,26 @@ IPCP::SendConfigureRequest()
|
||||
|
||||
// TODO: add VJC support
|
||||
|
||||
return Send(request.ToMbuf(Interface().MRU(),
|
||||
Interface().PacketOverhead())) == B_OK;
|
||||
return Send(request.ToNetBuffer(Interface().MRU())) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IPCP::SendConfigureAck(struct mbuf *packet)
|
||||
IPCP::SendConfigureAck(net_buffer *packet)
|
||||
{
|
||||
TRACE("IPCP: SendConfigureAck() state=%d\n", State());
|
||||
|
||||
if (!packet)
|
||||
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);
|
||||
|
||||
// verify items
|
||||
@@ -1271,22 +1473,29 @@ IPCP::SendConfigureAck(struct mbuf *packet)
|
||||
|
||||
|
||||
bool
|
||||
IPCP::SendConfigureNak(struct mbuf *packet)
|
||||
IPCP::SendConfigureNak(net_buffer *packet)
|
||||
{
|
||||
TRACE("IPCP: SendConfigureNak() state=%d\n", State());
|
||||
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
|
||||
if(nak->code == PPP_CONFIGURE_NAK) {
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet &nak = bufferheader.Data();
|
||||
|
||||
if (nak.code == PPP_CONFIGURE_NAK) {
|
||||
if (fNakCounter == 0) {
|
||||
// We sent enough naks. Let's try a reject.
|
||||
nak->code = PPP_CONFIGURE_REJECT;
|
||||
nak.code = PPP_CONFIGURE_REJECT;
|
||||
} else
|
||||
--fNakCounter;
|
||||
}
|
||||
|
||||
bufferheader.Sync();
|
||||
|
||||
return Send(packet) == B_OK;
|
||||
}
|
||||
|
||||
@@ -1299,81 +1508,78 @@ IPCP::SendTerminateRequest()
|
||||
--fTerminateCounter;
|
||||
fNextTimeout = system_time() + kIPCPStateMachineTimeout;
|
||||
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
net_buffer *packet = gBufferModule->create(256);
|
||||
if (!packet)
|
||||
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->id = fTerminateID = NextID();
|
||||
request->length = htons(4);
|
||||
|
||||
status = gBufferModule->trim(packet, 4);
|
||||
if (status != B_OK)
|
||||
return false;
|
||||
|
||||
return Send(packet) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IPCP::SendTerminateAck(struct mbuf *request)
|
||||
IPCP::SendTerminateAck(net_buffer *request)
|
||||
{
|
||||
TRACE("IPCP: SendTerminateAck() state=%d\n", State());
|
||||
|
||||
struct mbuf *reply = request;
|
||||
|
||||
ppp_lcp_packet *ack;
|
||||
net_buffer *reply = request;
|
||||
|
||||
if (!reply) {
|
||||
reply = m_gethdr(MT_DATA);
|
||||
if(!reply)
|
||||
reply = gBufferModule->create(256);
|
||||
ppp_lcp_packet *ack;
|
||||
status_t status = gBufferModule->append_size(reply, 1492, (void **)(&ack));
|
||||
if (status != B_OK) {
|
||||
gBufferModule->free(reply);
|
||||
return false;
|
||||
|
||||
reply->m_data += Interface().PacketOverhead();
|
||||
reply->m_pkthdr.len = reply->m_len = 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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
IPCP::SendCodeReject(struct mbuf *packet)
|
||||
IPCP::SendCodeReject(net_buffer *packet)
|
||||
{
|
||||
TRACE("IPCP: SendCodeReject() state=%d\n", State());
|
||||
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
M_PREPEND(packet, 4);
|
||||
// add some space for the header
|
||||
NetBufferPrepend<ppp_lcp_packet> bufferHeader(packet);
|
||||
if (bufferHeader.Status() != B_OK)
|
||||
return false;
|
||||
|
||||
// adjust packet if too big
|
||||
int32 adjust = Interface().MRU();
|
||||
if(packet->m_flags & M_PKTHDR) {
|
||||
adjust -= packet->m_pkthdr.len;
|
||||
} else
|
||||
adjust -= packet->m_len;
|
||||
ppp_lcp_packet &reject = bufferHeader.Data();
|
||||
|
||||
if(adjust < 0)
|
||||
m_adj(packet, adjust);
|
||||
reject.code = PPP_CODE_REJECT;
|
||||
reject.id = NextID();
|
||||
reject.length = htons(packet->size);
|
||||
|
||||
ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
|
||||
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);
|
||||
bufferHeader.Sync();
|
||||
|
||||
return Send(packet) == B_OK;
|
||||
}
|
||||
|
||||
@@ -9,9 +9,11 @@
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <KPPPProtocol.h>
|
||||
#include <Locker.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net_datalink.h>
|
||||
#include <net_datalink_protocol.h>
|
||||
#include <net/route.h>
|
||||
|
||||
|
||||
#define IPCP_PROTOCOL 0x8021
|
||||
@@ -71,10 +73,10 @@ class IPCP : public KPPPProtocol {
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
virtual status_t Send(struct mbuf *packet,
|
||||
virtual status_t Send(net_buffer *packet,
|
||||
uint16 protocolNumber = IPCP_PROTOCOL);
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
||||
status_t ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||
status_t ReceiveIPPacket(net_buffer *packet, uint16 protocolNumber);
|
||||
virtual void Pulse();
|
||||
|
||||
private:
|
||||
@@ -90,15 +92,15 @@ class IPCP : public KPPPProtocol {
|
||||
// events
|
||||
void TOGoodEvent();
|
||||
void TOBadEvent();
|
||||
void RCREvent(struct mbuf *packet);
|
||||
void RCRGoodEvent(struct mbuf *packet);
|
||||
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject);
|
||||
void RCAEvent(struct mbuf *packet);
|
||||
void RCNEvent(struct mbuf *packet);
|
||||
void RTREvent(struct mbuf *packet);
|
||||
void RTAEvent(struct mbuf *packet);
|
||||
void RUCEvent(struct mbuf *packet);
|
||||
void RXJBadEvent(struct mbuf *packet);
|
||||
void RCREvent(net_buffer *packet);
|
||||
void RCRGoodEvent(net_buffer *packet);
|
||||
void RCRBadEvent(net_buffer *nak, net_buffer *reject);
|
||||
void RCAEvent(net_buffer *packet);
|
||||
void RCNEvent(net_buffer *packet);
|
||||
void RTREvent(net_buffer *packet);
|
||||
void RTAEvent(net_buffer *packet);
|
||||
void RUCEvent(net_buffer *packet);
|
||||
void RXJBadEvent(net_buffer *packet);
|
||||
|
||||
// actions
|
||||
void IllegalEvent(ppp_event event);
|
||||
@@ -108,11 +110,11 @@ class IPCP : public KPPPProtocol {
|
||||
void InitializeRestartCount();
|
||||
void ResetRestartCount();
|
||||
bool SendConfigureRequest();
|
||||
bool SendConfigureAck(struct mbuf *packet);
|
||||
bool SendConfigureNak(struct mbuf *packet);
|
||||
bool SendConfigureAck(net_buffer *packet);
|
||||
bool SendConfigureNak(net_buffer *packet);
|
||||
bool SendTerminateRequest();
|
||||
bool SendTerminateAck(struct mbuf *request = NULL);
|
||||
bool SendCodeReject(struct mbuf *packet);
|
||||
bool SendTerminateAck(net_buffer *request = NULL);
|
||||
bool SendCodeReject(net_buffer *packet);
|
||||
|
||||
private:
|
||||
ipcp_configuration fLocalConfiguration, fPeerConfiguration;
|
||||
@@ -120,14 +122,14 @@ class IPCP : public KPPPProtocol {
|
||||
|
||||
// default route
|
||||
struct sockaddr_in fGateway;
|
||||
rtentry *fDefaultRoute;
|
||||
net_route *fDefaultRoute;
|
||||
|
||||
// used for local requests
|
||||
bool fRequestPrimaryDNS, fRequestSecondaryDNS;
|
||||
|
||||
// for state machine
|
||||
ppp_state fState;
|
||||
vint32 fID;
|
||||
int32 fID;
|
||||
|
||||
// counters and timers
|
||||
int32 fMaxRequest, fMaxTerminate, fMaxNak;
|
||||
|
||||
@@ -5,21 +5,24 @@
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <driver_settings.h>
|
||||
#include <core_funcs.h>
|
||||
#include <net_module.h>
|
||||
|
||||
#include <NetBufferUtilities.h>
|
||||
#include <net_buffer.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
#include <KPPPDefs.h>
|
||||
#include <KPPPInterface.h>
|
||||
#include <KPPPModule.h>
|
||||
|
||||
#include "Protocol.h"
|
||||
|
||||
#define IPCP_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/ipcp"
|
||||
|
||||
#define IPCP_MODULE_NAME NETWORK_MODULES_ROOT "ppp/ipcp"
|
||||
|
||||
struct protosw *gProto[IPPROTO_MAX];
|
||||
struct core_module_info *core = NULL;
|
||||
status_t std_ops(int32 op, ...);
|
||||
|
||||
net_stack_module_info *gStackModule = NULL;
|
||||
net_buffer_module_info *gBufferModule = NULL;
|
||||
|
||||
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// TODO: Remove isascii() (needed for inet_aton()) when our kernel is finished!
|
||||
@@ -28,7 +31,7 @@ extern "C"
|
||||
int
|
||||
isascii(char c)
|
||||
{
|
||||
return c & ~0x7f == 0; // If c is a 7 bit value.
|
||||
return ((c & (~0x7f)) == 0); // If c is a 7 bit value.
|
||||
}
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
@@ -75,14 +78,20 @@ std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
if(get_module(NET_CORE_MODULE_NAME, (module_info**) &core) != B_OK)
|
||||
if (get_module(NET_STACK_MODULE_NAME,
|
||||
(module_info**) &gStackModule) != B_OK)
|
||||
return B_ERROR;
|
||||
memset(gProto, 0, sizeof(struct protosw*) * IPPROTO_MAX);
|
||||
add_protosw(gProto, NET_LAYER1);
|
||||
if (get_module(NET_BUFFER_MODULE_NAME,
|
||||
(module_info **)&gBufferModule) != B_OK) {
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
break;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp pap ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
# for kernel_cpp.h and BLocker
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
|
||||
{
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
}
|
||||
|
||||
|
||||
KernelAddon pap :
|
||||
pap.cpp
|
||||
Protocol.cpp
|
||||
@@ -31,5 +25,5 @@ LinkAgainst pap : libkernelppp.a ;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
||||
: /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||
: pap ;
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <netinet/in.h>
|
||||
#include <core_funcs.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
static const bigtime_t kPAPTimeout = 3000000;
|
||||
// 3 seconds
|
||||
@@ -34,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
|
||||
PAPHandler::AddToRequest(KPPPConfigurePacket& request)
|
||||
{
|
||||
@@ -159,16 +167,18 @@ PAP::Down()
|
||||
|
||||
|
||||
status_t
|
||||
PAP::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
PAP::Send(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
// we do not encapsulate PAP packets
|
||||
m_freem(packet);
|
||||
TRACE("PAP: we should not send packet!\n");
|
||||
if (packet != NULL)
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PAP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
PAP::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
@@ -176,31 +186,30 @@ PAP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
if (protocolNumber != PAP_PROTOCOL)
|
||||
return PPP_UNHANDLED;
|
||||
|
||||
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return B_ERROR;
|
||||
ppp_lcp_packet &data = bufferheader.Data();
|
||||
|
||||
// check if the packet is meant for us:
|
||||
// only peer authenticators handle requests
|
||||
if(data->code == PPP_CONFIGURE_REQUEST && Side() != PPP_PEER_SIDE)
|
||||
if (data.code == PPP_CONFIGURE_REQUEST && Side() != PPP_PEER_SIDE)
|
||||
return PPP_UNHANDLED;
|
||||
// only local authenticators handle acks and naks
|
||||
if((data->code == PPP_CONFIGURE_ACK || data->code == PPP_CONFIGURE_NAK)
|
||||
if ((data.code == PPP_CONFIGURE_ACK || data.code == PPP_CONFIGURE_NAK)
|
||||
&& Side() != PPP_LOCAL_SIDE)
|
||||
return PPP_UNHANDLED;
|
||||
|
||||
// remove padding
|
||||
int32 length = packet->m_len;
|
||||
if(packet->m_flags & M_PKTHDR)
|
||||
length = packet->m_pkthdr.len;
|
||||
length -= ntohs(data->length);
|
||||
if(length)
|
||||
m_adj(packet, -length);
|
||||
int32 length = packet->size;
|
||||
length -= ntohs(data.length);
|
||||
|
||||
if(ntohs(data->length) < 4)
|
||||
if (ntohs(data.length) < 4)
|
||||
return B_ERROR;
|
||||
|
||||
// packet is freed by event methods
|
||||
// code values are the same as for LCP (but very reduced)
|
||||
switch(data->code) {
|
||||
switch (data.code) {
|
||||
case PPP_CONFIGURE_REQUEST:
|
||||
RREvent(packet);
|
||||
break;
|
||||
@@ -320,19 +329,22 @@ PAP::TOBadEvent()
|
||||
|
||||
|
||||
void
|
||||
PAP::RREvent(struct mbuf *packet)
|
||||
PAP::RREvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("PAP: RREvent() state=%d\n", State());
|
||||
|
||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
||||
int32 length = ntohs(request->length);
|
||||
uint8 *data = request->data;
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return;
|
||||
ppp_lcp_packet &request = bufferheader.Data();
|
||||
int32 length = ntohs(request.length);
|
||||
uint8 *data = request.data;
|
||||
uint8 *userLength = data;
|
||||
uint8 *passwordLength = data + 1 + data[0];
|
||||
|
||||
// make sure the length values are all okay
|
||||
if (6 + *userLength + *passwordLength > length) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -357,15 +369,19 @@ PAP::RREvent(struct mbuf *packet)
|
||||
|
||||
|
||||
void
|
||||
PAP::RAEvent(struct mbuf *packet)
|
||||
PAP::RAEvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("PAP: RAEvent() state=%d\n", State());
|
||||
|
||||
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return;
|
||||
ppp_lcp_packet &lcp_hdr = bufferheader.Data();
|
||||
if (fRequestID != lcp_hdr.id) {
|
||||
// this packet is not a reply to our request
|
||||
|
||||
// TODO: log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -381,20 +397,24 @@ PAP::RAEvent(struct mbuf *packet)
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PAP::RNEvent(struct mbuf *packet)
|
||||
PAP::RNEvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("PAP: RNEvent() state=%d\n", State());
|
||||
|
||||
if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return;
|
||||
ppp_lcp_packet &lcp_hdr = bufferheader.Data();
|
||||
if (fRequestID != lcp_hdr.id) {
|
||||
// this packet is not a reply to our request
|
||||
|
||||
// TODO: log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -410,7 +430,7 @@ PAP::RNEvent(struct mbuf *packet)
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
@@ -429,68 +449,72 @@ PAP::SendRequest()
|
||||
--fRequestCounter;
|
||||
fNextTimeout = system_time() + kPAPTimeout;
|
||||
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
net_buffer *packet = gBufferModule->create(256);
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet *request;
|
||||
gBufferModule->append_size(packet, 1492, (void **)&request);
|
||||
|
||||
const char *username = Interface().Username(), *password = Interface().Password();
|
||||
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->id = fRequestID = NextID();
|
||||
request->length = htons(packet->m_len);
|
||||
request->length = htons(packcketLenth);
|
||||
uint8 *data = request->data;
|
||||
data[0] = strlen(username);
|
||||
memcpy(data + 1, username, strlen(username));
|
||||
data[1 + data[0]] = strlen(password);
|
||||
memcpy(data + 2 + data[0], password, strlen(password));
|
||||
|
||||
gBufferModule->trim(packet, packcketLenth);
|
||||
|
||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PAP::SendAck(struct mbuf *packet)
|
||||
PAP::SendAck(net_buffer *packet)
|
||||
{
|
||||
TRACE("PAP: SendAck() state=%d\n", State());
|
||||
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet *ack = mtod(packet, ppp_lcp_packet*);
|
||||
ack->code = PPP_CONFIGURE_ACK;
|
||||
packet->m_len = 5;
|
||||
if(packet->m_flags & M_PKTHDR)
|
||||
packet->m_pkthdr.len = 5;
|
||||
ack->length = htons(packet->m_len);
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return false;
|
||||
ppp_lcp_packet &ack = bufferheader.Data();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
|
||||
nak->code = PPP_CONFIGURE_NAK;
|
||||
packet->m_len = 5;
|
||||
if(packet->m_flags & M_PKTHDR)
|
||||
packet->m_pkthdr.len = 5;
|
||||
nak->length = htons(packet->m_len);
|
||||
|
||||
nak->data[0] = 0;
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return false;
|
||||
ppp_lcp_packet &nak = bufferheader.Data();
|
||||
nak.code = PPP_CONFIGURE_NAK;
|
||||
nak.length = htons(5);
|
||||
nak.data[0] = 0;
|
||||
gBufferModule->trim(packet, 5);
|
||||
|
||||
return Interface().Send(packet, PAP_PROTOCOL) == B_OK;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ class PAPHandler : public KPPPOptionHandler {
|
||||
{ return fOwner; }
|
||||
|
||||
virtual status_t AddToRequest(KPPPConfigurePacket& request);
|
||||
virtual status_t SendingAck(const KPPPConfigurePacket&);
|
||||
virtual status_t ParseRequest(const KPPPConfigurePacket& request,
|
||||
int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject);
|
||||
|
||||
@@ -57,8 +58,8 @@ class PAP : public KPPPProtocol {
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber);
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||
virtual void Pulse();
|
||||
|
||||
private:
|
||||
@@ -70,9 +71,9 @@ class PAP : public KPPPProtocol {
|
||||
// events
|
||||
void TOGoodEvent();
|
||||
void TOBadEvent();
|
||||
void RREvent(struct mbuf *packet);
|
||||
void RAEvent(struct mbuf *packet);
|
||||
void RNEvent(struct mbuf *packet);
|
||||
void RREvent(net_buffer *packet);
|
||||
void RAEvent(net_buffer *packet);
|
||||
void RNEvent(net_buffer *packet);
|
||||
|
||||
// actions
|
||||
void ReportUpFailedEvent();
|
||||
@@ -80,13 +81,13 @@ class PAP : public KPPPProtocol {
|
||||
void ReportDownEvent();
|
||||
void InitializeRestartCount();
|
||||
bool SendRequest();
|
||||
bool SendAck(struct mbuf *packet);
|
||||
bool SendNak(struct mbuf *packet);
|
||||
bool SendAck(net_buffer *packet);
|
||||
bool SendNak(net_buffer *packet);
|
||||
|
||||
private:
|
||||
// for state machine
|
||||
pap_state fState;
|
||||
vint32 fID;
|
||||
int32 fID;
|
||||
|
||||
// counters and timers
|
||||
int32 fMaxRequest;
|
||||
|
||||
@@ -5,23 +5,22 @@
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <driver_settings.h>
|
||||
#include <core_funcs.h>
|
||||
#include <net_module.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
#include <KPPPInterface.h>
|
||||
#include <KPPPModule.h>
|
||||
|
||||
#include "Protocol.h"
|
||||
|
||||
#define PAP_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/pap"
|
||||
|
||||
#define PAP_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pap"
|
||||
|
||||
struct core_module_info *core = NULL;
|
||||
net_stack_module_info *gStackModule = NULL;
|
||||
net_buffer_module_info *gBufferModule = NULL;
|
||||
status_t std_ops(int32 op, ...);
|
||||
|
||||
|
||||
static
|
||||
bool
|
||||
static bool
|
||||
add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
|
||||
driver_parameter *settings, ppp_module_key_type type)
|
||||
{
|
||||
@@ -62,12 +61,18 @@ std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
if(get_module(NET_CORE_MODULE_NAME, (module_info**) &core) != B_OK)
|
||||
if (get_module(NET_STACK_MODULE_NAME, (module_info**) &gStackModule) != B_OK)
|
||||
return B_ERROR;
|
||||
if (get_module(NET_BUFFER_MODULE_NAME,
|
||||
(module_info **)&gBufferModule) != B_OK) {
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp ppp ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||
# Needed for <support/Errors.h> and maybe other stuff.
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
KernelAddon ppp :
|
||||
ppp.cpp
|
||||
;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking :
|
||||
/boot/home/config/add-ons/kernel/network/ppp
|
||||
: ppp ;
|
||||
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright 2014, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Lin Longzhou, [email protected]
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
#include <new>
|
||||
|
||||
#include <ethernet.h>
|
||||
#include <ether_driver.h>
|
||||
#include <net_buffer.h>
|
||||
#include <net_datalink_protocol.h>
|
||||
|
||||
#include <NetBufferUtilities.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <KPPPManager.h>
|
||||
#include <ppp_device.h>
|
||||
|
||||
#define PPP_HEADER_LENGTH (8 + ETHER_HEADER_LENGTH)
|
||||
|
||||
|
||||
net_buffer* create_buffer_for_frame(uint8 *frame, uint16 frame_size);
|
||||
|
||||
static const bigtime_t kLinkCheckInterval = 1000000;
|
||||
// 1 second
|
||||
|
||||
net_buffer_module_info *gBufferModule;
|
||||
ppp_interface_module_info* gPPPInterfaceModule;
|
||||
static net_stack_module_info *sStackModule;
|
||||
|
||||
static mutex sListLock;
|
||||
static DoublyLinkedList<ppp_device> sCheckList;
|
||||
static sem_id sLinkChangeSemaphore;
|
||||
static thread_id sLinkCheckerThread;
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
//
|
||||
|
||||
status_t
|
||||
ppp_init(const char *name, net_device **_device)
|
||||
{
|
||||
// ppp device
|
||||
dprintf("%s: entering!\n", __func__);
|
||||
|
||||
if (strncmp(name, "ppp", 3)) {
|
||||
dprintf("[%s] not ppp device\n", name);
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
dprintf("[%s] is ppp device\n", name);
|
||||
|
||||
status_t status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
// ppp_device *device = new (std::nothrow) ppp_device;
|
||||
ppp_interface_id idInterface = gPPPInterfaceModule->CreateInterfaceWithName(name, 0);
|
||||
KPPPInterface * pppInterface = gPPPInterfaceModule->GetInterface(idInterface);
|
||||
|
||||
if (idInterface <= 0 || pppInterface == NULL) {
|
||||
if (idInterface <= 0)
|
||||
dprintf("%s: idInterface:%ld\n", __func__, idInterface);
|
||||
else
|
||||
dprintf("%s: pppInterface == NULL %ld\n", __func__, idInterface);
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
// Ifnet available until interface up phase
|
||||
ppp_device *device = (ppp_device *)pppInterface->Ifnet();
|
||||
if (device == NULL) {
|
||||
dprintf("%s: can not get ppp_device\n", __func__);
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
strcpy(device->name, name);
|
||||
device->flags = (IFF_BROADCAST | IFF_LINK) & (~IFF_UP);
|
||||
device->type = IFT_PPP;
|
||||
device->mtu = 1492;
|
||||
device->frame_size = 1500;
|
||||
device->media = IFM_ACTIVE | IFM_ETHER;
|
||||
device->header_length = PPP_HEADER_LENGTH;
|
||||
|
||||
status =sStackModule->init_fifo(&(device->ppp_fifo), "ppp_fifo", 10 * 1500);
|
||||
// 10 ppp packet at most
|
||||
if (status < B_OK)
|
||||
return(status);
|
||||
|
||||
TRACE("[%s] finish\n", "allocate ppp_device");
|
||||
*_device = device;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_uninit(net_device *device)
|
||||
{
|
||||
dprintf("%s: uninit ppp\n", __func__);
|
||||
ppp_device *ppp_dev=(ppp_device *)device;
|
||||
|
||||
sStackModule->uninit_fifo(&(ppp_dev->ppp_fifo));
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
|
||||
// delete ppp_dev->KPPP_Interface;
|
||||
delete ppp_dev;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_up(net_device *_device)
|
||||
{
|
||||
dprintf("ppp_up\n");
|
||||
ppp_device *device = (ppp_device *)_device;
|
||||
|
||||
if (device->KPPP_Interface == NULL) {
|
||||
dprintf("%s: warning! can not find pppinterface KPPP_Interface\n", __func__);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (device->KPPP_Interface->Up() != true) {
|
||||
dprintf("%s: warning! KPPP_Interface->Up() failure\n", __func__);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
device->mtu = device->frame_size - device->header_length;
|
||||
// s_pppoe_dev = device;
|
||||
|
||||
dprintf("%s: congratulations! Find pppinterface (device->KPPP_Interface)\n", __func__);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ppp_down(net_device *_device)
|
||||
{
|
||||
dprintf("%s\n", __func__);
|
||||
ppp_device *device = (ppp_device *)_device;
|
||||
device->KPPP_Interface->Down();
|
||||
|
||||
MutexLocker _(sListLock);
|
||||
|
||||
// if the device is still part of the list, remove it
|
||||
if (device->GetDoublyLinkedListLink()->next != NULL
|
||||
|| device->GetDoublyLinkedListLink()->previous != NULL
|
||||
|| device == sCheckList.Head())
|
||||
sCheckList.Remove(device);
|
||||
|
||||
// device->KPPP_Interface = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_control(net_device *_device, int32 op, void *argument,
|
||||
size_t length)
|
||||
{
|
||||
TRACE("%s %ld\n", __func__, op);
|
||||
ppp_device *device = (ppp_device *)_device;
|
||||
|
||||
if (device->KPPP_Interface == NULL) {
|
||||
dprintf("%s: can not find KPPP_Interface for ppp\n", __func__);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return device->KPPP_Interface->Control(op, argument, length);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_send_data(net_device *_device, net_buffer *buffer)
|
||||
{
|
||||
TRACE("%s\n", __func__);
|
||||
ppp_device *device = (ppp_device *)_device;
|
||||
|
||||
if (buffer->size > device->frame_size || buffer->size < device->header_length) {
|
||||
device->stats.send.errors++;
|
||||
dprintf("sorry! fail send ppp packet, size wrong!\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (device->KPPP_Interface == NULL) {
|
||||
device->stats.send.errors++;
|
||||
dprintf("Fail send ppp packet, no eth for ppp!\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
size_t net_buffer_size = buffer->size;
|
||||
// store buffer->size in case buffer freed in KPPP_Interface->Send
|
||||
status_t status = device->KPPP_Interface->Send(buffer, 0x0021); // IP_PROTOCOL 0x0021
|
||||
|
||||
if (status != B_OK) {
|
||||
device->stats.send.errors++;
|
||||
dprintf("KPPP_Interface->Send(buffer, 0x0021 IP) fail\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
device->stats.send.packets++;
|
||||
device->stats.send.bytes += net_buffer_size;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_receive_data(net_device *_device, net_buffer **_buffer)
|
||||
{
|
||||
TRACE("%s\n", __func__);
|
||||
ppp_device *device = (ppp_device *)_device;
|
||||
|
||||
if (device->KPPP_Interface == NULL)
|
||||
return B_FILE_ERROR;
|
||||
|
||||
TRACE("%s: trying fifo_dequeue_buffer\n", __func__);
|
||||
status_t status = sStackModule->fifo_dequeue_buffer(&(device->ppp_fifo), 0, 10000000, _buffer);
|
||||
|
||||
if (status < B_OK) {
|
||||
TRACE("sorry! can not fifo_dequeue_buffer!\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
// (*_buffer)->interface_address = NULL; // strange need to put here
|
||||
device->stats.receive.bytes += (*_buffer)->size;
|
||||
device->stats.receive.packets++;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_set_mtu(net_device *_device, size_t mtu)
|
||||
{
|
||||
ppp_device *device = (ppp_device *)_device;
|
||||
|
||||
if (mtu > device->frame_size - ETHER_HEADER_LENGTH - 8
|
||||
|| mtu <= ETHER_HEADER_LENGTH + 8 + 10)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
device->mtu = mtu;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_set_promiscuous(net_device *_device, bool promiscuous)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_set_media(net_device *device, uint32 media)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_add_multicast(struct net_device *_device, const sockaddr *_address)
|
||||
{
|
||||
// ppp_device *device = (ppp_device *)_device;
|
||||
|
||||
if (_address->sa_family != AF_LINK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
const sockaddr_dl *address = (const sockaddr_dl *)_address;
|
||||
if (address->sdl_type != IFT_ETHER)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_remove_multicast(struct net_device *_device, const sockaddr *_address)
|
||||
{
|
||||
// ppp_device *device = (ppp_device *)_device;
|
||||
|
||||
if (_address->sa_family != AF_LINK)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
const sockaddr_dl *address = (const sockaddr_dl *)_address;
|
||||
if (address->sdl_type != IFT_ETHER)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ppp_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
{
|
||||
status_t status = get_module(NET_STACK_MODULE_NAME,
|
||||
(module_info **)&sStackModule);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
status = get_module(PPP_INTERFACE_MODULE_NAME,
|
||||
(module_info**)&gPPPInterfaceModule);
|
||||
if (status < B_OK) {
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return status;
|
||||
}
|
||||
|
||||
new (&sCheckList) DoublyLinkedList<ppp_device>;
|
||||
// static C++ objects are not initialized in the module startup
|
||||
|
||||
sLinkCheckerThread = -1;
|
||||
|
||||
sLinkChangeSemaphore = create_sem(0, "ppp link change");
|
||||
if (sLinkChangeSemaphore < B_OK) {
|
||||
put_module(PPP_INTERFACE_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return sLinkChangeSemaphore;
|
||||
}
|
||||
|
||||
mutex_init(&sListLock, "ppp devices");
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
{
|
||||
delete_sem(sLinkChangeSemaphore);
|
||||
|
||||
status_t status;
|
||||
wait_for_thread(sLinkCheckerThread, &status);
|
||||
|
||||
mutex_destroy(&sListLock);
|
||||
|
||||
put_module(PPP_INTERFACE_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
net_device_module_info spppModule = {
|
||||
{
|
||||
"network/devices/ppp/v1",
|
||||
0,
|
||||
ppp_std_ops
|
||||
},
|
||||
ppp_init,
|
||||
ppp_uninit,
|
||||
ppp_up,
|
||||
ppp_down,
|
||||
ppp_control,
|
||||
ppp_send_data,
|
||||
ppp_receive_data,
|
||||
ppp_set_mtu,
|
||||
ppp_set_promiscuous,
|
||||
ppp_set_media,
|
||||
ppp_add_multicast,
|
||||
ppp_remove_multicast,
|
||||
};
|
||||
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *)&spppModule,
|
||||
NULL
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders kernel net ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
KernelAddon ppp_frame :
|
||||
ppp_frame.cpp
|
||||
;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||
: ppp_frame ;
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright 2014, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Lin Longzhou, [email protected]
|
||||
*/
|
||||
|
||||
|
||||
#include <ethernet.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net_datalink_protocol.h>
|
||||
#include <net_datalink.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <PPPControl.h>
|
||||
#include <ppp_device.h>
|
||||
|
||||
struct ppp_frame_protocol : net_datalink_protocol {
|
||||
};
|
||||
|
||||
|
||||
static net_stack_module_info *sStackModule;
|
||||
|
||||
status_t
|
||||
ppp_deframe(net_device* device, net_buffer* buffer)
|
||||
{
|
||||
TRACE("%s: buffer type:%lx\n", __func__, buffer->type);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
status_t
|
||||
ppp_frame_init(struct net_interface* interface, net_domain* domain,
|
||||
net_datalink_protocol** _protocol)
|
||||
{
|
||||
// We only support a single type!
|
||||
dprintf("in function: %s::%s\n", __FILE__, __func__);
|
||||
if (interface->device->type != IFT_PPP)
|
||||
return B_BAD_TYPE;
|
||||
|
||||
ppp_frame_protocol* protocol;
|
||||
|
||||
status_t status = sStackModule->register_device_deframer(interface->device,
|
||||
&ppp_deframe);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = sStackModule->register_domain_device_handler(
|
||||
interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE), domain);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = sStackModule->register_domain_device_handler(
|
||||
interface->device, B_NET_FRAME_TYPE_IPV4, domain);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
// Locally received buffers don't need a domain device handler, as the
|
||||
// buffer reception is handled internally.
|
||||
|
||||
protocol = new(std::nothrow) ppp_frame_protocol;
|
||||
if (protocol == NULL) {
|
||||
sStackModule->unregister_device_deframer(interface->device);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
*_protocol = protocol;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_frame_uninit(net_datalink_protocol* protocol)
|
||||
{
|
||||
sStackModule->unregister_device_deframer(protocol->interface->device);
|
||||
sStackModule->unregister_device_handler(protocol->interface->device, 0);
|
||||
|
||||
delete protocol;
|
||||
TRACE("%s\n", __func__);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_frame_send_data(net_datalink_protocol* protocol, net_buffer* buffer)
|
||||
{
|
||||
TRACE("%s: next module is %s\n", __func__, protocol->next->module->info.name);
|
||||
return protocol->next->module->send_data(protocol->next, buffer);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_frame_up(net_datalink_protocol* protocol)
|
||||
{
|
||||
dprintf("in function: %s\n", __func__);
|
||||
|
||||
return protocol->next->module->interface_up(protocol->next);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ppp_frame_down(net_datalink_protocol* protocol)
|
||||
{
|
||||
dprintf("%s::%s: entry\n", __FILE__, __func__);
|
||||
protocol->next->module->interface_down(protocol->next);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ppp_frame_change_address(net_datalink_protocol* protocol,
|
||||
net_interface_address* address, int32 option,
|
||||
const struct sockaddr* oldAddress, const struct sockaddr* newAddress)
|
||||
{
|
||||
TRACE("in function: %s::%s\n", __FILE__, __func__);
|
||||
return protocol->next->module->change_address(protocol->next, address,
|
||||
option, oldAddress, newAddress);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
PPP_module_control(int32 option, void* argument, size_t length)
|
||||
{
|
||||
// control_net_module_args* args=(control_net_module_args*)argument;
|
||||
|
||||
if (option < PPPC_CONTROL_MODULE || option > PPP_CONTROL_OPS_END)
|
||||
return B_ERROR;
|
||||
|
||||
// if (args->name != PPP_INTERFACE_MODULE_NAME)
|
||||
// return B_ERROR;
|
||||
|
||||
switch(option)
|
||||
{
|
||||
case PPPC_CREATE_INTERFACE:
|
||||
// process_CreateInterface(args->data, args->length);
|
||||
case PPPC_CREATE_INTERFACE_WITH_NAME:
|
||||
case PPPC_DELETE_INTERFACE:
|
||||
case PPPC_BRING_INTERFACE_UP:
|
||||
case PPPC_BRING_INTERFACE_DOWN:
|
||||
case PPPC_CONTROL_INTERFACE:
|
||||
case PPPC_GET_INTERFACES:
|
||||
case PPPC_COUNT_INTERFACES:
|
||||
case PPPC_FIND_INTERFACE_WITH_SETTINGS:
|
||||
|
||||
// interface control
|
||||
case PPPC_GET_INTERFACE_INFO:
|
||||
case PPPC_SET_USERNAME:
|
||||
case PPPC_SET_PASSWORD:
|
||||
case PPPC_SET_ASK_BEFORE_CONNECTING:
|
||||
// ppp_up uses this in order to finalize a connection request
|
||||
case PPPC_SET_MRU:
|
||||
case PPPC_SET_CONNECT_ON_DEMAND:
|
||||
case PPPC_SET_AUTO_RECONNECT:
|
||||
case PPPC_HAS_INTERFACE_SETTINGS:
|
||||
case PPPC_GET_STATISTICS:
|
||||
// handler access
|
||||
case PPPC_CONTROL_DEVICE:
|
||||
case PPPC_CONTROL_PROTOCOL:
|
||||
case PPPC_CONTROL_OPTION_HANDLER:
|
||||
case PPPC_CONTROL_LCP_EXTENSION:
|
||||
case PPPC_CONTROL_CHILD:
|
||||
// KPPPDevice
|
||||
case PPPC_GET_DEVICE_INFO:
|
||||
// KPPPProtocol
|
||||
case PPPC_GET_PROTOCOL_INFO:
|
||||
// Common/mixed ops
|
||||
case PPPC_ENABLE:
|
||||
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||
|
||||
// these two control ops use the ppp_report_request structure
|
||||
case PPPC_ENABLE_REPORTS:
|
||||
case PPPC_DISABLE_REPORTS:
|
||||
|
||||
case PPP_CONTROL_OPS_END:
|
||||
case PPPC_CONTROL_MODULE:
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ppp_frame_control(net_datalink_protocol* protocol, int32 option,
|
||||
void* argument, size_t length)
|
||||
{
|
||||
TRACE("%s: option:%ld\n", __func__, option);
|
||||
|
||||
if (option >= PPPC_CONTROL_MODULE && option <=PPP_CONTROL_OPS_END)
|
||||
{
|
||||
status_t status =PPP_module_control(option, argument, length);
|
||||
// gPPPInterfaceModule->ControlInterface(1, option, argument, length);
|
||||
return status;
|
||||
}
|
||||
|
||||
return protocol->next->module->control(protocol->next, option, argument,
|
||||
length);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ppp_frame_join_multicast(net_datalink_protocol* protocol,
|
||||
const sockaddr* address)
|
||||
{
|
||||
TRACE("in function: %s\n", __func__);
|
||||
return protocol->next->module->join_multicast(protocol->next, address);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ppp_frame_leave_multicast(net_datalink_protocol* protocol,
|
||||
const sockaddr* address)
|
||||
{
|
||||
TRACE("in function: %s\n", __func__);
|
||||
return protocol->next->module->leave_multicast(protocol->next, address);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
pppoe_frame_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
if (get_module(NET_STACK_MODULE_NAME,
|
||||
(module_info **)&sStackModule) != B_OK)
|
||||
return B_ERROR;
|
||||
return B_OK;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_OK;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static net_datalink_protocol_module_info sPPPFrameModule = {
|
||||
{
|
||||
"network/datalink_protocols/ppp_frame/v1",
|
||||
0,
|
||||
pppoe_frame_std_ops
|
||||
},
|
||||
ppp_frame_init,
|
||||
ppp_frame_uninit,
|
||||
ppp_frame_send_data,
|
||||
ppp_frame_up,
|
||||
ppp_frame_down,
|
||||
ppp_frame_change_address,
|
||||
ppp_frame_control,
|
||||
ppp_frame_join_multicast,
|
||||
ppp_frame_leave_multicast,
|
||||
};
|
||||
|
||||
|
||||
module_info* modules[] = {
|
||||
(module_info*)&sPPPFrameModule,
|
||||
NULL
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FStandardOSHeaders ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
# We need the public network headers also when not compiling for Haiku.
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
# UsePrivateHeaders net ;
|
||||
|
||||
UsePrivateHeaders kernel net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
KernelAddon KPPPManager :
|
||||
KPPPManager.cpp
|
||||
;
|
||||
|
||||
LinkAgainst KPPPManager : libkernelppp.a ;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking : /boot/home/config/add-ons/kernel/haiku_network/ppp
|
||||
: KPPPManager ;
|
||||
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright 2006-2014, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, [email protected]
|
||||
* Lin Longzhou, [email protected]
|
||||
*/
|
||||
|
||||
#include <net_stack.h>
|
||||
#include <NetBufferUtilities.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <ppp_device.h>
|
||||
#include <KPPPManager.h>
|
||||
|
||||
|
||||
struct entry_private : ppp_interface_entry, DoublyLinkedListLinkImpl<entry_private> {
|
||||
};
|
||||
|
||||
static DoublyLinkedList<entry_private> sEntryList;
|
||||
|
||||
net_buffer_module_info* gBufferModule = NULL;
|
||||
net_stack_module_info* gStackModule = NULL;
|
||||
// static struct net_interface* sinterface;
|
||||
static mutex sListLock;
|
||||
static uint32 ppp_interface_count;
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
static KPPPInterface * GetInterface(ppp_interface_id ID);
|
||||
|
||||
static ppp_interface_id
|
||||
CreateInterface(const driver_settings *settings, ppp_interface_id parentID)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
if (parentID > 0) {
|
||||
TRACE("Not support Multi_Link yet!\n");
|
||||
return 0l;
|
||||
}
|
||||
|
||||
if (settings == NULL) {
|
||||
TRACE("No driver_settings yet!\n");
|
||||
return 0l;
|
||||
}
|
||||
|
||||
ppp_interface_count++;
|
||||
|
||||
if (GetInterface(ppp_interface_count) != NULL)
|
||||
return 0l;
|
||||
|
||||
entry_private* pentry = new (std::nothrow) entry_private;
|
||||
memset(pentry, 0, sizeof(entry_private));
|
||||
pentry->accessing = ppp_interface_count;
|
||||
sEntryList.Add(pentry);
|
||||
|
||||
KPPPInterface *device = new (std::nothrow) KPPPInterface(NULL,
|
||||
pentry, ppp_interface_count, NULL, NULL);
|
||||
|
||||
if (device == NULL || pentry == NULL) {
|
||||
TRACE("device or pentry is NULL\n");
|
||||
ppp_interface_count--;
|
||||
return 0l;
|
||||
}
|
||||
|
||||
TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
|
||||
|
||||
return ppp_interface_count; // only support 1 ppp connection right now
|
||||
}
|
||||
|
||||
|
||||
static ppp_interface_id
|
||||
CreateInterfaceWithName(const char *name, ppp_interface_id parentID)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
if (parentID > 0) {
|
||||
dprintf("Not support Multi_Link yet!\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (strncmp(name, "ppp", 3)) {
|
||||
dprintf("%s is not ppp device!\n", name);
|
||||
return(0);
|
||||
}
|
||||
|
||||
ppp_interface_count++;
|
||||
if (GetInterface(ppp_interface_count) != NULL) {
|
||||
TRACE("PPP Interface already exist!\n");
|
||||
return 0l;
|
||||
}
|
||||
|
||||
entry_private* pentry = new (std::nothrow) entry_private;
|
||||
memset(pentry, 0, sizeof(entry_private));
|
||||
pentry->accessing = ppp_interface_count;
|
||||
sEntryList.Add(pentry);
|
||||
|
||||
KPPPInterface* device = new (std::nothrow) KPPPInterface(name,
|
||||
pentry, ppp_interface_count, NULL, NULL);
|
||||
|
||||
|
||||
if (device == NULL || pentry == NULL) {
|
||||
TRACE("can not create ppp interface!\n");
|
||||
ppp_interface_count--;
|
||||
return 0l;
|
||||
}
|
||||
|
||||
TRACE("setting ppp_interface_count %ld\n", ppp_interface_count);
|
||||
|
||||
return ppp_interface_count;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
DeleteInterface(ppp_interface_id ID)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
DoublyLinkedList<entry_private>::Iterator iterator
|
||||
= sEntryList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
entry_private* pentry = iterator.Next();
|
||||
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||
pentry->deleting = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
RemoveInterface(ppp_interface_id ID)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
if (ID <= 0 || ID > ppp_interface_count)
|
||||
return false;
|
||||
|
||||
DoublyLinkedList<entry_private>::Iterator iterator
|
||||
= sEntryList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
entry_private* pentry = iterator.Next();
|
||||
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||
pentry->deleting = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static net_device *
|
||||
RegisterInterface(ppp_interface_id ID)
|
||||
{
|
||||
// MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
entry_private* entry = NULL;
|
||||
|
||||
DoublyLinkedList<entry_private>::Iterator iterator
|
||||
= sEntryList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
entry_private* pentry = iterator.Next();
|
||||
if ((ppp_interface_id)pentry->accessing == ID) {
|
||||
entry = pentry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry == NULL)
|
||||
return NULL;
|
||||
|
||||
ppp_device *device = new (std::nothrow) ppp_device;
|
||||
if (device == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(device, 0, sizeof(ppp_device));
|
||||
device->KPPP_Interface = entry->interface;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
static KPPPInterface *
|
||||
GetInterface(ppp_interface_id ID)
|
||||
{
|
||||
// MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
DoublyLinkedList<entry_private>::Iterator iterator
|
||||
= sEntryList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
entry_private* pentry = iterator.Next();
|
||||
TRACE("testing interface id:%ld\n", pentry->accessing);
|
||||
if ((ppp_interface_id)(pentry->accessing) == ID) {
|
||||
TRACE("get interface id:%ld\n", ID);
|
||||
return pentry->interface;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("can not get interface id:%ld\n", ID);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
UnregisterInterface(ppp_interface_id ID)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
if (ID <= 0 || ID > ppp_interface_count)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t length)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
if (ID <= 0 || ID > ppp_interface_count)
|
||||
return B_ERROR;
|
||||
|
||||
DoublyLinkedList<entry_private>::Iterator iterator
|
||||
= sEntryList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
entry_private* pentry = iterator.Next();
|
||||
if ((ppp_interface_id)pentry->accessing == ID)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static int32
|
||||
GetInterfaces(ppp_interface_id *interfaces, int32 count, ppp_interface_filter filter)
|
||||
{
|
||||
MutexLocker _(sListLock);
|
||||
|
||||
if (count <= 0 || count > (int32)ppp_interface_count)
|
||||
return(0);
|
||||
|
||||
uint32 ppp_count = 0;
|
||||
|
||||
DoublyLinkedList<entry_private>::Iterator iterator
|
||||
= sEntryList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
entry_private* pentry = iterator.Next();
|
||||
interfaces[ppp_count] = pentry->accessing;
|
||||
ppp_count++;
|
||||
}
|
||||
|
||||
return ppp_count;
|
||||
}
|
||||
|
||||
|
||||
static int32
|
||||
CountInterfaces(ppp_interface_filter filter)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
uint32 ppp_count = 0;
|
||||
|
||||
DoublyLinkedList<entry_private>::Iterator iterator
|
||||
= sEntryList.GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
iterator.Next();
|
||||
ppp_count++;
|
||||
}
|
||||
|
||||
return ppp_count;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
EnableReports(ppp_report_type type, thread_id thread, int32 flags)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
return; // need more portrait
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DisableReports(ppp_report_type type, thread_id thread)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
return; // need more portrait
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
DoesReport(ppp_report_type type, thread_id thread)
|
||||
{
|
||||
MutexLocker _(sListLock); // auto_lock
|
||||
|
||||
return false; // need more portrait
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
KPPPManager_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
mutex_init(&sListLock, "KPPPManager");
|
||||
new (&sEntryList) DoublyLinkedList<entry_private>;
|
||||
// static C++ objects are not initialized in the module startup
|
||||
ppp_interface_count = 0;
|
||||
|
||||
if (get_module(NET_STACK_MODULE_NAME, (module_info**)&gStackModule)
|
||||
!= B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (get_module(NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule)
|
||||
!= B_OK) {
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
mutex_destroy(&sListLock);
|
||||
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_OK;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ppp_interface_module_info sKPPPManagerModule = {
|
||||
{
|
||||
PPP_INTERFACE_MODULE_NAME,
|
||||
0,
|
||||
KPPPManager_std_ops
|
||||
},
|
||||
CreateInterface,
|
||||
CreateInterfaceWithName,
|
||||
DeleteInterface,
|
||||
RemoveInterface,
|
||||
RegisterInterface,
|
||||
GetInterface,
|
||||
UnregisterInterface,
|
||||
ControlInterface,
|
||||
GetInterfaces,
|
||||
CountInterfaces,
|
||||
EnableReports,
|
||||
DisableReports,
|
||||
DoesReport
|
||||
};
|
||||
|
||||
|
||||
module_info* modules[] = {
|
||||
(module_info*)&sKPPPManagerModule,
|
||||
NULL
|
||||
};
|
||||
@@ -3,11 +3,12 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <NetBufferUtilities.h>
|
||||
#include <net_buffer.h>
|
||||
|
||||
#include "DiscoveryPacket.h"
|
||||
|
||||
#include <core_funcs.h>
|
||||
|
||||
|
||||
DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID)
|
||||
: fCode(code),
|
||||
fSessionID(sessionID),
|
||||
@@ -16,18 +17,26 @@ DiscoveryPacket::DiscoveryPacket(uint8 code, uint16 sessionID)
|
||||
}
|
||||
|
||||
|
||||
DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start)
|
||||
DiscoveryPacket::DiscoveryPacket(net_buffer *packet, uint32 start)
|
||||
{
|
||||
// decode packet
|
||||
uint8 *data = mtod(packet, uint8*);
|
||||
data += start;
|
||||
pppoe_header *header = (pppoe_header*) data;
|
||||
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK) {
|
||||
dprintf("NetBufferHeaderReader create fail\n");
|
||||
fInitStatus = B_ERROR;
|
||||
return;
|
||||
}
|
||||
pppoe_header &header = bufferheader.Data();
|
||||
|
||||
SetCode(header->code);
|
||||
SetCode(header.code);
|
||||
|
||||
uint16 length = ntohs(header->length);
|
||||
uint16 length = ntohs(header.length);
|
||||
|
||||
if(length > packet->m_len - PPPoE_HEADER_SIZE - start) {
|
||||
if(length > packet->size - PPPoE_HEADER_SIZE) {
|
||||
dprintf("packet size less than pppoe payload\n");
|
||||
dprintf("pppoe payload:%d\n", length);
|
||||
dprintf("PPPoE_HEADER_SIZE:%d\n", PPPoE_HEADER_SIZE);
|
||||
dprintf("packet->size:%ld\n", packet->size);
|
||||
fInitStatus = B_ERROR;
|
||||
return;
|
||||
// there are no tags (or one corrupted tag)
|
||||
@@ -37,7 +46,7 @@ DiscoveryPacket::DiscoveryPacket(struct mbuf *packet, uint32 start)
|
||||
pppoe_tag *tag;
|
||||
|
||||
while(position <= length - 4) {
|
||||
tag = (pppoe_tag*) (header->data + position);
|
||||
tag = (pppoe_tag*) (header.data + position);
|
||||
position += ntohs(tag->length) + 4;
|
||||
|
||||
AddTag(ntohs(tag->type), tag->data, ntohs(tag->length));
|
||||
@@ -116,13 +125,21 @@ DiscoveryPacket::TagWithType(uint16 type) const
|
||||
}
|
||||
|
||||
|
||||
struct mbuf*
|
||||
DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
||||
net_buffer*
|
||||
DiscoveryPacket::ToNetBuffer(uint32 MTU)
|
||||
{
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
packet->m_data += reserve;
|
||||
net_buffer *packet = gBufferModule->create(256);
|
||||
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->type = PPPoE_TYPE;
|
||||
@@ -137,7 +154,7 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
||||
|
||||
// make sure we have enough space left
|
||||
if(MTU - length < tag->length) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -150,7 +167,11 @@ DiscoveryPacket::ToMbuf(uint32 MTU, uint32 reserve)
|
||||
}
|
||||
|
||||
header->length = htons(length);
|
||||
packet->m_pkthdr.len = packet->m_len = length + PPPoE_HEADER_SIZE;
|
||||
status = gBufferModule->trim(packet, length + PPPoE_HEADER_SIZE);
|
||||
if (status != B_OK) {
|
||||
dprintf("trim buffer failure\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <TemplateList.h>
|
||||
|
||||
#define ETHER_HDR_LEN 14
|
||||
|
||||
enum PPPoE_TAG_TYPE {
|
||||
END_OF_LIST = 0x0000,
|
||||
@@ -37,13 +38,13 @@ typedef struct pppoe_tag {
|
||||
uint16 type;
|
||||
uint16 length;
|
||||
uint8 data[0];
|
||||
};
|
||||
} pppoe_tag;
|
||||
|
||||
|
||||
class DiscoveryPacket {
|
||||
public:
|
||||
DiscoveryPacket(uint8 code, uint16 sessionID = 0x0000);
|
||||
DiscoveryPacket(struct mbuf *packet, uint32 start = 0);
|
||||
DiscoveryPacket(net_buffer *packet, uint32 start = 0);
|
||||
~DiscoveryPacket();
|
||||
|
||||
status_t InitCheck() const
|
||||
@@ -66,8 +67,8 @@ class DiscoveryPacket {
|
||||
pppoe_tag *TagAt(int32 index) const;
|
||||
pppoe_tag *TagWithType(uint16 type) const;
|
||||
|
||||
struct mbuf *ToMbuf(uint32 MTU, uint32 reserve = ETHER_HDR_LEN);
|
||||
// the user is responsible for freeing the mbuf
|
||||
net_buffer *ToNetBuffer(uint32 MTU);
|
||||
// the user is responsible for freeing the net_buffer
|
||||
|
||||
private:
|
||||
uint8 fCode;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel network ppp pppoe ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
|
||||
if $(TARGET_PLATFORM) != haiku {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
|
||||
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
# for kernel_cpp.h and BLocker
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
libkernelppp headers ] : true ;
|
||||
|
||||
|
||||
{
|
||||
SubDirC++Flags -fno-rtti ;
|
||||
}
|
||||
|
||||
|
||||
KernelAddon pppoe :
|
||||
pppoe.cpp
|
||||
PPPoEDevice.cpp
|
||||
@@ -32,5 +26,5 @@ LinkAgainst pppoe : libkernelppp.a ;
|
||||
|
||||
# Installation
|
||||
HaikuInstall install-networking
|
||||
: /boot/home/config/add-ons/kernel/obos_network/ppp
|
||||
: /boot/home/config/add-ons/kernel/haiku/ppp
|
||||
: pppoe ;
|
||||
|
||||
@@ -8,10 +8,15 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#include <ethernet.h>
|
||||
#include <ether_driver.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
class PPPoEDevice;
|
||||
|
||||
#define B_NET_FRAME_TYPE_PPPOE B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE)
|
||||
#define B_NET_FRAME_TYPE_PPPOE_DISCOVERY B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE_DISCOVERY)
|
||||
|
||||
#define PPPoE_QUERY_REPORT_SIZE 2048
|
||||
#define PPPoE_QUERY_REPORT 'PoEQ'
|
||||
@@ -60,14 +65,14 @@ typedef struct complete_pppoe_header {
|
||||
|
||||
|
||||
// defined in pppoe.cpp
|
||||
extern ifnet *FindPPPoEInterface(const char *name);
|
||||
extern net_device *FindPPPoEInterface(const char *name);
|
||||
extern uint32 NewHostUniq();
|
||||
extern void add_device(PPPoEDevice *device);
|
||||
extern void remove_device(PPPoEDevice *device);
|
||||
|
||||
#if DEBUG
|
||||
// defined in PPPoEDevice.cpp
|
||||
extern void dump_packet(struct mbuf *packet);
|
||||
extern void dump_packet(net_buffer *packet);
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
|
||||
@@ -3,25 +3,39 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
#include <ethernet.h>
|
||||
#include <ether_driver.h>
|
||||
|
||||
#include "PPPoEDevice.h"
|
||||
#include "DiscoveryPacket.h"
|
||||
|
||||
#include <core_funcs.h>
|
||||
#include <cstdlib>
|
||||
|
||||
// from libkernelppp
|
||||
#include <settings_tools.h>
|
||||
|
||||
extern net_stack_module_info *gStackModule;
|
||||
extern net_buffer_module_info *gBufferModule;
|
||||
extern status_t
|
||||
pppoe_input(void *cookie, net_device *_device, net_buffer *packet);
|
||||
|
||||
#if DEBUG
|
||||
static char sDigits[] = "0123456789ABCDEF";
|
||||
void
|
||||
dump_packet(struct mbuf *packet)
|
||||
dump_packet(net_buffer *packet)
|
||||
{
|
||||
if (!packet)
|
||||
return;
|
||||
|
||||
uint8 *data = mtod(packet, uint8*);
|
||||
BufferHeaderReader<uint8> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return;
|
||||
uint8 &buffer = bufferheader.Data();
|
||||
uint8 *data = &buffer;
|
||||
uint8 buffer[33];
|
||||
uint8 bufferIndex = 0;
|
||||
|
||||
@@ -38,6 +52,8 @@ dump_packet(struct mbuf *packet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
|
||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||
|
||||
SetMTU(1494);
|
||||
// MTU size does not contain PPP header
|
||||
|
||||
if (!settings)
|
||||
dprintf("%s::%s: settings is NULL\n", __FILE__, __func__);
|
||||
|
||||
// find ethernet device
|
||||
const char *interfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings);
|
||||
if(!interfaceName)
|
||||
return;
|
||||
finterfaceName = get_parameter_value(PPPoE_INTERFACE_KEY, settings);
|
||||
TRACE("%s::%s: finterfaceName is %s\n", __FILE__, __func__,
|
||||
finterfaceName ? finterfaceName : "NULL");
|
||||
|
||||
fACName = get_parameter_value(PPPoE_AC_NAME_KEY, settings);
|
||||
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 (!fEthernetIfnet)
|
||||
TRACE("PPPoEDevice::ctor: could not find ethernet interface\n");
|
||||
else
|
||||
TRACE("%s::%s: Find Ethernet device", __FILE__, __func__);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -85,8 +110,10 @@ PPPoEDevice::PPPoEDevice(KPPPInterface& interface, driver_parameter *settings)
|
||||
status_t
|
||||
PPPoEDevice::InitCheck() const
|
||||
{
|
||||
return EthernetIfnet() && EthernetIfnet()->output
|
||||
&& KPPPDevice::InitCheck() == B_OK ? B_OK : B_ERROR;
|
||||
if (KPPPDevice::InitCheck() != B_OK)
|
||||
dprintf("%s::%s: KPPPDevice::InitCheck() has error\n", __FILE__, __func__);
|
||||
|
||||
return KPPPDevice::InitCheck() == B_OK ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +128,24 @@ PPPoEDevice::Up()
|
||||
if (IsUp())
|
||||
return true;
|
||||
|
||||
fEthernetIfnet = FindPPPoEInterface(finterfaceName);
|
||||
|
||||
if (fEthernetIfnet == NULL) {
|
||||
dprintf("%s::%s: fEthernetIfnet %s not found\n", __FILE__, __func__, finterfaceName);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(fEtherAddr, fEthernetIfnet->address.data, ETHER_ADDRESS_LENGTH);
|
||||
dprintf("ppp's corresponding addr is %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
fEtherAddr[0], fEtherAddr[1], fEtherAddr[2], fEtherAddr[3],
|
||||
fEtherAddr[4], fEtherAddr[5]);
|
||||
|
||||
if (fEthernetIfnet->module == NULL) {
|
||||
dprintf("%s::%s: fEthernetIfnet->module not found\n", __FILE__,
|
||||
__func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
add_device(this);
|
||||
|
||||
fState = INITIAL;
|
||||
@@ -125,19 +170,21 @@ PPPoEDevice::Up()
|
||||
discovery.AddTag(END_OF_LIST, NULL, 0);
|
||||
|
||||
// set up PPP header
|
||||
struct mbuf *packet = discovery.ToMbuf(MTU());
|
||||
net_buffer *packet = discovery.ToNetBuffer(MTU());
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
// create destination
|
||||
struct ether_header *ethernetHeader;
|
||||
struct sockaddr destination;
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
destination.sa_family = AF_UNSPEC;
|
||||
// create ether header
|
||||
NetBufferPrepend<ether_header> ethernetHeader(packet);
|
||||
if (ethernetHeader.Status() != B_OK)
|
||||
return false;
|
||||
ether_header &header = ethernetHeader.Data();
|
||||
|
||||
memset(header.destination, 0xff, ETHER_ADDRESS_LENGTH);
|
||||
memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||
header.type = htons(ETHER_TYPE_PPPOE_DISCOVERY);
|
||||
ethernetHeader.Sync();
|
||||
// raw packet with ethernet header
|
||||
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)
|
||||
if (fAttempts > 0 && !UpStarted()) {
|
||||
@@ -151,13 +198,24 @@ PPPoEDevice::Up()
|
||||
fState = PADI_SENT;
|
||||
// needed before sending, otherwise we might not get all packets
|
||||
|
||||
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK) {
|
||||
status_t status = gStackModule->register_device_handler(fEthernetIfnet,
|
||||
B_NET_FRAME_TYPE_PPPOE_DISCOVERY, &pppoe_input, NULL);
|
||||
if (status != B_OK)
|
||||
return false;
|
||||
|
||||
status = gStackModule->register_device_handler(fEthernetIfnet,
|
||||
B_NET_FRAME_TYPE_PPPOE, &pppoe_input, NULL);
|
||||
if (status != B_OK)
|
||||
return false;
|
||||
|
||||
if (EthernetIfnet()->module->send_data(EthernetIfnet(), packet) != B_OK) {
|
||||
fState = INITIAL;
|
||||
fAttempts = 0;
|
||||
ERROR("PPPoEDevice::Up(): EthernetIfnet()->output() failed!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
dprintf("PPPoEDevice::Up(): EthernetIfnet()->output() success!\n");
|
||||
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
||||
|
||||
return true;
|
||||
@@ -169,6 +227,11 @@ PPPoEDevice::Down()
|
||||
{
|
||||
TRACE("PPPoEDevice: Down()\n");
|
||||
|
||||
gStackModule->unregister_device_handler(fEthernetIfnet,
|
||||
B_NET_FRAME_TYPE_PPPOE_DISCOVERY);
|
||||
gStackModule->unregister_device_handler(fEthernetIfnet,
|
||||
B_NET_FRAME_TYPE_PPPOE);
|
||||
|
||||
remove_device(this);
|
||||
|
||||
if (InitCheck() != B_OK)
|
||||
@@ -191,9 +254,9 @@ PPPoEDevice::Down()
|
||||
DiscoveryPacket discovery(PADT, SessionID());
|
||||
discovery.AddTag(END_OF_LIST, NULL, 0);
|
||||
|
||||
struct mbuf *packet = discovery.ToMbuf(MTU());
|
||||
net_buffer *packet = discovery.ToNetBuffer(MTU());
|
||||
if (!packet) {
|
||||
ERROR("PPPoEDevice::Down(): ToMbuf() failed; MTU=%ld\n", MTU());
|
||||
ERROR("PPPoEDevice::Down(): ToNetBuffer() failed; MTU=%ld\n", MTU());
|
||||
DownEvent();
|
||||
return false;
|
||||
}
|
||||
@@ -205,13 +268,13 @@ PPPoEDevice::Down()
|
||||
destination.sa_family = AF_UNSPEC;
|
||||
// raw packet with ethernet header
|
||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||
ethernetHeader->type = ETHER_TYPE_PPPOE_DISCOVERY;
|
||||
memcpy(ethernetHeader->destination, fPeer, sizeof(fPeer));
|
||||
|
||||
// reset connection settings
|
||||
memset(fPeer, 0xFF, sizeof(fPeer));
|
||||
|
||||
EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL);
|
||||
EthernetIfnet()->module->send_data(EthernetIfnet(), packet);
|
||||
DownEvent();
|
||||
|
||||
return true;
|
||||
@@ -242,7 +305,7 @@ PPPoEDevice::CountOutputBytes() const
|
||||
|
||||
|
||||
status_t
|
||||
PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
PPPoEDevice::Send(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
// Send() is only for PPP packets. PPPoE packets are sent directly to ethernet.
|
||||
|
||||
@@ -252,41 +315,46 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
return B_ERROR;
|
||||
else if (InitCheck() != B_OK || protocolNumber != 0) {
|
||||
ERROR("PPPoEDevice::Send(): InitCheck() != B_OK!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (!IsUp()) {
|
||||
ERROR("PPPoEDevice::Send(): no connection!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return PPP_NO_CONNECTION;
|
||||
}
|
||||
|
||||
uint16 length = packet->m_flags & M_PKTHDR ? packet->m_pkthdr.len : packet->m_len;
|
||||
uint16 length = packet->size;
|
||||
|
||||
// encapsulate packet into pppoe header
|
||||
M_PREPEND(packet, PPPoE_HEADER_SIZE);
|
||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||
header->version = PPPoE_VERSION;
|
||||
header->type = PPPoE_TYPE;
|
||||
header->code = 0x00;
|
||||
header->sessionID = SessionID();
|
||||
header->length = htons(length);
|
||||
NetBufferPrepend<pppoe_header> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK)
|
||||
return B_ERROR;
|
||||
pppoe_header &header = bufferheader.Data();
|
||||
header.version = PPPoE_VERSION;
|
||||
header.type = PPPoE_TYPE;
|
||||
header.code = 0x00;
|
||||
header.sessionID = SessionID();
|
||||
header.length = htons(length);
|
||||
bufferheader.Sync();
|
||||
|
||||
// create destination
|
||||
struct ether_header *ethernetHeader;
|
||||
struct sockaddr destination;
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
destination.sa_family = AF_UNSPEC;
|
||||
// create ether header
|
||||
NetBufferPrepend<ether_header> ethernetHeader(packet);
|
||||
if (ethernetHeader.Status() != B_OK)
|
||||
return false;
|
||||
ether_header ðheader = ethernetHeader.Data();
|
||||
|
||||
memcpy(ethheader.destination, fPeer, ETHER_ADDRESS_LENGTH);
|
||||
memcpy(ethheader.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||
ethheader.type = htons(ETHER_TYPE_PPPOE);
|
||||
ethernetHeader.Sync();
|
||||
// raw packet with ethernet header
|
||||
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");
|
||||
|
||||
if(EthernetIfnet()->output(EthernetIfnet(), packet, &destination, NULL) != B_OK) {
|
||||
if (EthernetIfnet()->module->send_data(EthernetIfnet(), packet) != B_OK) {
|
||||
ERROR("PPPoEDevice::Send(): EthernetIfnet()->output() failed!\n");
|
||||
remove_device(this);
|
||||
DownEvent();
|
||||
@@ -299,57 +367,83 @@ PPPoEDevice::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
|
||||
|
||||
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)
|
||||
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(!completeHeader) {
|
||||
m_freem(packet);
|
||||
if (InitCheck() != B_OK || IsDown()) {
|
||||
dprintf("PPPoED InitCheck fail or IsDown\n");
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
uint8 ethernetSource[6];
|
||||
memcpy(ethernetSource, completeHeader->ethernetHeader.ether_shost, sizeof(fPeer));
|
||||
status_t result = B_OK;
|
||||
struct sockaddr_dl& source = *(struct sockaddr_dl*)packet->source;
|
||||
memcpy(ethernetSource, source.sdl_data, sizeof(fPeer));
|
||||
|
||||
if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOE) {
|
||||
m_adj(packet, ETHER_HDR_LEN);
|
||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||
int32 PPP_Packet_Type = B_NET_FRAME_TYPE(source.sdl_type,
|
||||
ntohs(source.sdl_e_type));
|
||||
// bufferheader.Remove();
|
||||
// bufferheader.Sync();
|
||||
|
||||
if(!IsUp() || header->version != PPPoE_VERSION || header->type != PPPoE_TYPE
|
||||
|| header->code != 0x0 || header->sessionID != SessionID()) {
|
||||
m_freem(packet);
|
||||
if (PPP_Packet_Type == B_NET_FRAME_TYPE_PPPOE) {
|
||||
TRACE("ETHER_TYPE_PPPOE\n");
|
||||
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK) {
|
||||
TRACE("creat NetBufferHeaderReader fail\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
} else if(completeHeader->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC) {
|
||||
m_adj(packet, ETHER_HDR_LEN);
|
||||
pppoe_header *header = mtod(packet, pppoe_header*);
|
||||
}
|
||||
|
||||
if (PPP_Packet_Type == B_NET_FRAME_TYPE_PPPOE_DISCOVERY) {
|
||||
dprintf("ETHER_TYPE_PPPOE_DISCOVERY\n");
|
||||
NetBufferHeaderReader<pppoe_header> bufferheader(packet);
|
||||
if (bufferheader.Status() != B_OK) {
|
||||
dprintf("create NetBufferHeaderReader fail\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
pppoe_header &header = bufferheader.Data();
|
||||
|
||||
// we do not need to check HOST_UNIQ tag as this is done in pppoe.cpp
|
||||
if(header->version != PPPoE_VERSION || header->type != PPPoE_TYPE) {
|
||||
m_freem(packet);
|
||||
if (header.version != PPPoE_VERSION || header.type != PPPoE_TYPE) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail version type wrong\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (IsDown()) {
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail PPPoEDev IsDown\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
DiscoveryPacket discovery(packet);
|
||||
switch(discovery.Code()) {
|
||||
case PADO: {
|
||||
dprintf("processing PADO\n");
|
||||
if (fState != PADI_SENT) {
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive faile not PADI_Sent \n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -364,9 +458,9 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
switch (tag->type) {
|
||||
case SERVICE_NAME:
|
||||
if (!hasServiceName && (!ServiceName()
|
||||
|| (strlen(ServiceName()) == tag->length)
|
||||
|| ((strlen(ServiceName()) == tag->length)
|
||||
&& !memcmp(tag->data, ServiceName(),
|
||||
tag->length))) {
|
||||
tag->length)))) {
|
||||
hasServiceName = true;
|
||||
reply.AddTag(tag->type, tag->data, tag->length);
|
||||
}
|
||||
@@ -374,9 +468,9 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
|
||||
case AC_NAME:
|
||||
if (!hasACName && (!ACName()
|
||||
|| (strlen(ACName()) == tag->length)
|
||||
|| ((strlen(ACName()) == tag->length)
|
||||
&& !memcmp(tag->data, ACName(),
|
||||
tag->length))) {
|
||||
tag->length)))) {
|
||||
hasACName = true;
|
||||
reply.AddTag(tag->type, tag->data, tag->length);
|
||||
}
|
||||
@@ -390,7 +484,8 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
case SERVICE_NAME_ERROR:
|
||||
case AC_SYSTEM_ERROR:
|
||||
case GENERIC_ERROR:
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::generic error faile\n");
|
||||
return B_ERROR;
|
||||
break;
|
||||
|
||||
@@ -400,59 +495,68 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
}
|
||||
|
||||
if (!hasServiceName) {
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive faile no svc name\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
dprintf("reply.AddTag\n");
|
||||
reply.AddTag(HOST_UNIQ, &fHostUniq, sizeof(fHostUniq));
|
||||
reply.AddTag(END_OF_LIST, NULL, 0);
|
||||
struct mbuf *replyPacket = reply.ToMbuf(MTU());
|
||||
net_buffer *replyPacket = reply.ToNetBuffer(MTU());
|
||||
if (!replyPacket) {
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail no reply pack\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
memcpy(fPeer, ethernetSource, sizeof(fPeer));
|
||||
memcpy(fPeer, ethernetSource, ETHER_ADDRESS_LENGTH);
|
||||
|
||||
// create destination
|
||||
struct ether_header *ethernetHeader;
|
||||
struct sockaddr destination;
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
destination.sa_family = AF_UNSPEC;
|
||||
// create ether header
|
||||
NetBufferPrepend<ether_header> ethernetHeader(replyPacket);
|
||||
if (ethernetHeader.Status() != B_OK)
|
||||
return false;
|
||||
ether_header &header = ethernetHeader.Data();
|
||||
|
||||
memcpy(header.destination, fPeer, ETHER_ADDRESS_LENGTH);
|
||||
memcpy(header.source, fEtherAddr, ETHER_ADDRESS_LENGTH);
|
||||
header.type=htons(ETHER_TYPE_PPPOE_DISCOVERY);
|
||||
ethernetHeader.Sync();
|
||||
// raw packet with ethernet header
|
||||
ethernetHeader = (struct ether_header*) destination.sa_data;
|
||||
ethernetHeader->ether_type = ETHERTYPE_PPPOEDISC;
|
||||
memcpy(ethernetHeader->ether_dhost, fPeer, sizeof(fPeer));
|
||||
|
||||
fState = PADR_SENT;
|
||||
|
||||
if(EthernetIfnet()->output(EthernetIfnet(), replyPacket, &destination,
|
||||
NULL) != B_OK) {
|
||||
m_freem(packet);
|
||||
if (EthernetIfnet()->module->send_data(EthernetIfnet(), replyPacket) != B_OK) {
|
||||
gBufferModule->free(replyPacket);
|
||||
dprintf("PPPoEDevice::Receive fail send PADR\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fNextTimeout = system_time() + PPPoE_TIMEOUT;
|
||||
} break;
|
||||
|
||||
}
|
||||
break;
|
||||
case PADS:
|
||||
dprintf("procesing PADS\n");
|
||||
if (fState != PADR_SENT
|
||||
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))) {
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive PADS but no PADR sent\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fSessionID = header->sessionID;
|
||||
fSessionID = header.sessionID;
|
||||
fState = OPENED;
|
||||
fNextTimeout = 0;
|
||||
UpEvent();
|
||||
break;
|
||||
|
||||
case PADT:
|
||||
dprintf("procesing PADT\n");
|
||||
if (!IsUp()
|
||||
|| memcmp(ethernetSource, fPeer, sizeof(fPeer))
|
||||
|| header->sessionID != SessionID()) {
|
||||
m_freem(packet);
|
||||
|| header.sessionID != SessionID()) {
|
||||
// gBufferModule->free(packet);
|
||||
dprintf("PPPoEDevice::Receive fail not up yet\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -465,14 +569,15 @@ PPPoEDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
break;
|
||||
|
||||
default:
|
||||
m_freem(packet);
|
||||
dprintf("PPPoEDevice::Receive fail unknown pppoed code\n");
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
} else
|
||||
result = B_ERROR;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
return result;
|
||||
dprintf("PPPoEDevice::Receive PADX fine!\n");
|
||||
// gBufferModule->free(packet);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -480,7 +585,6 @@ void
|
||||
PPPoEDevice::Pulse()
|
||||
{
|
||||
// We use Pulse() for timeout of connection establishment.
|
||||
|
||||
if (fNextTimeout == 0 || IsUp() || IsDown())
|
||||
return;
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
#include <KPPPDevice.h>
|
||||
|
||||
#include <net/if_types.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
|
||||
enum pppoe_state {
|
||||
INITIAL,
|
||||
@@ -25,7 +28,7 @@ class PPPoEDevice : public KPPPDevice {
|
||||
public:
|
||||
PPPoEDevice(KPPPInterface& interface, driver_parameter *settings);
|
||||
|
||||
ifnet *EthernetIfnet() const
|
||||
net_device *EthernetIfnet() const
|
||||
{ return fEthernetIfnet; }
|
||||
|
||||
const uint8 *Peer() const
|
||||
@@ -50,17 +53,19 @@ class PPPoEDevice : public KPPPDevice {
|
||||
|
||||
virtual uint32 CountOutputBytes() const;
|
||||
|
||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber = 0);
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber = 0);
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber = 0);
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber = 0);
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
private:
|
||||
ifnet *fEthernetIfnet;
|
||||
net_device *fEthernetIfnet;
|
||||
uint8 fPeer[6];
|
||||
uint8 fEtherAddr[6];
|
||||
uint16 fSessionID;
|
||||
uint32 fHostUniq;
|
||||
const char *fACName, *fServiceName;
|
||||
const char *finterfaceName;
|
||||
|
||||
uint32 fAttempts;
|
||||
bigtime_t fNextTimeout;
|
||||
|
||||
@@ -5,34 +5,46 @@
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <driver_settings.h>
|
||||
#include <core_funcs.h>
|
||||
#include <net_module.h>
|
||||
|
||||
#include <ethernet_module.h>
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
#include <ByteOrder.h>
|
||||
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <net_datalink.h> // for get_interface and control
|
||||
#include <net_stack.h>
|
||||
#include <NetBufferUtilities.h>
|
||||
|
||||
#include <KPPPInterface.h>
|
||||
#include <KPPPModule.h>
|
||||
#include <KPPPUtils.h>
|
||||
#include <LockerHelper.h>
|
||||
|
||||
#include "PPPoEDevice.h"
|
||||
#include "DiscoveryPacket.h"
|
||||
|
||||
|
||||
typedef struct pppoe_query {
|
||||
ifnet *ethernetIfnet;
|
||||
net_device *ethernetIfnet;
|
||||
uint32 hostUniq;
|
||||
thread_id receiver;
|
||||
} pppoe_query;
|
||||
|
||||
#define PPPoE_MODULE_NAME NETWORK_MODULES_ROOT "ppp/pppoe"
|
||||
#define PPPoE_MODULE_NAME "network/ppp/pppoe"
|
||||
|
||||
net_stack_module_info *gStackModule = NULL;
|
||||
net_buffer_module_info *gBufferModule = NULL;
|
||||
net_datalink_module_info *sDatalinkModule = NULL;
|
||||
|
||||
struct core_module_info *core = NULL;
|
||||
static struct ethernet_module_info *sEthernet;
|
||||
static int32 sHostUniq = 0;
|
||||
status_t std_ops(int32 op, ...);
|
||||
|
||||
static BLocker sLock("PPPoEList");
|
||||
// static mutex sLock("PPPoEList");
|
||||
|
||||
static TemplateList<PPPoEDevice*> *sDevices;
|
||||
static TemplateList<pppoe_query*> *sQueries;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
ifnet *current = get_interfaces();
|
||||
for(; current; current = current->if_next) {
|
||||
if(current->if_type == IFT_ETHER && current->if_name
|
||||
&& !strcmp(current->if_name, name))
|
||||
return current;
|
||||
net_interface* ethernetInterfaceOfPPPOE = NULL;
|
||||
net_domain* domain = NULL;
|
||||
|
||||
domain = gStackModule->get_domain(AF_INET);
|
||||
ethernetInterfaceOfPPPOE = get_interface_by_name(domain, name);
|
||||
|
||||
if (ethernetInterfaceOfPPPOE == NULL) {
|
||||
TRACE("get_interface_by_name can not find eth\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ethernetInterfaceOfPPPOE->device)
|
||||
return ethernetInterfaceOfPPPOE->device;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -105,7 +141,7 @@ add_device(PPPoEDevice *device)
|
||||
{
|
||||
TRACE("PPPoE: add_device()\n");
|
||||
|
||||
LockerHelper locker(sLock);
|
||||
// MutexLocker locker(sLock);
|
||||
if (!sDevices->HasItem(device))
|
||||
sDevices->AddItem(device);
|
||||
}
|
||||
@@ -116,84 +152,124 @@ remove_device(PPPoEDevice *device)
|
||||
{
|
||||
TRACE("PPPoE: remove_device()\n");
|
||||
|
||||
LockerHelper locker(sLock);
|
||||
// MutexLocker locker(sLock);
|
||||
sDevices->RemoveItem(device);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
pppoe_input(struct mbuf *packet)
|
||||
status_t
|
||||
pppoe_input(void *cookie, net_device *_device, net_buffer *packet)
|
||||
{
|
||||
if (!packet)
|
||||
return;
|
||||
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;
|
||||
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
|
||||
&& header->pppoeHeader.length <= PPPoE_QUERY_REPORT_SIZE) {
|
||||
// MutexLocker locker(sLock);
|
||||
|
||||
if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
|
||||
&& ntohs(header.length) <= PPPoE_QUERY_REPORT_SIZE) {
|
||||
for (int32 index = 0; index < sDevices->CountItems(); index++) {
|
||||
query = sQueries->ItemAt(index);
|
||||
|
||||
if(query && query->ethernetIfnet == sourceIfnet) {
|
||||
if(header->pppoeHeader.code == PADO) {
|
||||
if (query) {// && query->ethernetIfnet == sourceIfnet) {
|
||||
if (header.code == PADO) {
|
||||
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||
if (discovery.InitCheck() != B_OK) {
|
||||
ERROR("PPPoE: received corrupted discovery packet!\n");
|
||||
m_freem(packet);
|
||||
return;
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
pppoe_tag *hostTag = discovery.TagWithType(HOST_UNIQ);
|
||||
if (hostTag && hostTag->length == 4
|
||||
&& *((uint32*)hostTag->data) == query->hostUniq) {
|
||||
SendQueryPacket(query, discovery);
|
||||
m_freem(packet);
|
||||
return;
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("in pppoed processing sDevices->CountItems(): %ld\n", sDevices->CountItems());
|
||||
|
||||
for (int32 index = 0; index < sDevices->CountItems(); index++) {
|
||||
device = sDevices->ItemAt(index);
|
||||
|
||||
if(device && device->EthernetIfnet() == sourceIfnet) {
|
||||
if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOE
|
||||
&& header->pppoeHeader.sessionID == device->SessionID()) {
|
||||
TRACE("device->SessionID() %d, header.sessionID: %d\n", device->SessionID(),
|
||||
header.sessionID);
|
||||
|
||||
if (device) { // && device->EthernetIfnet() == sourceIfnet) {
|
||||
if (specificType == B_NET_FRAME_TYPE_PPPOE
|
||||
&& header.sessionID == device->SessionID()) {
|
||||
TRACE("PPPoE: session packet\n");
|
||||
device->Receive(packet);
|
||||
return;
|
||||
} else if(header->ethernetHeader.ether_type == ETHERTYPE_PPPOEDISC
|
||||
&& header->pppoeHeader.code != PADI
|
||||
&& header->pppoeHeader.code != PADR
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
|
||||
&& header.code != PADI
|
||||
&& header.code != PADR
|
||||
&& !device->IsDown()) {
|
||||
TRACE("PPPoE: discovery packet\n");
|
||||
|
||||
DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
|
||||
if (discovery.InitCheck() != B_OK) {
|
||||
ERROR("PPPoE: received corrupted discovery packet!\n");
|
||||
m_freem(packet);
|
||||
return;
|
||||
gBufferModule->free(packet);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ);
|
||||
if(header->pppoeHeader.code == PADT || (tag && tag->length == 4
|
||||
if (header.code == PADT || (tag && tag->length == 4
|
||||
&& *((uint32*)tag->data) == device->HostUniq())) {
|
||||
device->Receive(packet);
|
||||
return;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ERROR("PPPoE: No device found for packet from: %s\n", sourceIfnet->if_name);
|
||||
m_freem(packet);
|
||||
ERROR("PPPoE: No device found for packet from: %s\n", "ethernet");
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -231,14 +307,14 @@ control(uint32 op, void *data, size_t length)
|
||||
int32 position = 0, count = 0;
|
||||
char *names = (char*) data;
|
||||
|
||||
ifnet *current = get_interfaces();
|
||||
for(; current; current = current->if_next) {
|
||||
if(current->if_type == IFT_ETHER && current->if_name) {
|
||||
if(position + strlen(current->if_name) + 1 > length)
|
||||
net_device *current = NULL; // get_interfaces();
|
||||
for (; current; current = NULL) {
|
||||
if (current->type == IFT_ETHER && current->name) {
|
||||
if (position + strlen(current->name) + 1 > length)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
strcpy(names + position, current->if_name);
|
||||
position += strlen(current->if_name);
|
||||
strcpy(names + position, current->name);
|
||||
position += strlen(current->name);
|
||||
names[position++] = 0;
|
||||
++count;
|
||||
}
|
||||
@@ -263,16 +339,19 @@ control(uint32 op, void *data, size_t length)
|
||||
query.hostUniq = NewHostUniq();
|
||||
query.receiver = request->receiver;
|
||||
|
||||
sLock.Lock();
|
||||
{
|
||||
// MutexLocker tlocker(sLock);
|
||||
TRACE("add query\n");
|
||||
sQueries->AddItem(&query);
|
||||
sLock.Unlock();
|
||||
}
|
||||
|
||||
snooze(2000000);
|
||||
// wait two seconds for results
|
||||
|
||||
sLock.Lock();
|
||||
{
|
||||
// MutexLocker tlocker(sLock);
|
||||
TRACE("remove query\n");
|
||||
sQueries->RemoveItem(&query);
|
||||
sLock.Unlock();
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
@@ -300,30 +379,38 @@ std_ops(int32 op, ...)
|
||||
{
|
||||
switch(op) {
|
||||
case B_MODULE_INIT:
|
||||
if(get_module(NET_CORE_MODULE_NAME, (module_info**)&core) != B_OK)
|
||||
if (get_module(NET_STACK_MODULE_NAME,
|
||||
(module_info**)&gStackModule) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if(get_module(NET_ETHERNET_MODULE_NAME,
|
||||
(module_info**) &sEthernet) != B_OK) {
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
if (get_module(NET_DATALINK_MODULE_NAME,
|
||||
(module_info **)&sDatalinkModule) != B_OK) {
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
set_max_linkhdr(2 + PPPoE_HEADER_SIZE + ETHER_HDR_LEN);
|
||||
if (get_module(NET_BUFFER_MODULE_NAME,
|
||||
(module_info **)&gBufferModule) != B_OK) {
|
||||
put_module(NET_DATALINK_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// set_max_linkhdr(2 + PPPoE_HEADER_SIZE + ETHER_HDR_LEN);
|
||||
// 2 bytes for PPP header
|
||||
sDevices = new TemplateList<PPPoEDevice*>;
|
||||
sQueries = new TemplateList<pppoe_query*>;
|
||||
sEthernet->set_pppoe_receiver(pppoe_input);
|
||||
|
||||
TRACE("PPPoE: Registered PPPoE receiver.\n");
|
||||
return B_OK;
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
delete sQueries;
|
||||
delete sDevices;
|
||||
sEthernet->unset_pppoe_receiver();
|
||||
TRACE("PPPoE: Unregistered PPPoE receiver.\n");
|
||||
put_module(NET_CORE_MODULE_NAME);
|
||||
put_module(NET_ETHERNET_MODULE_NAME);
|
||||
put_module(NET_BUFFER_MODULE_NAME);
|
||||
put_module(NET_DATALINK_MODULE_NAME);
|
||||
put_module(NET_STACK_MODULE_NAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -10,6 +10,9 @@ if $(TARGET_PLATFORM) != haiku {
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
|
||||
UsePrivateHeaders libroot net ;
|
||||
UsePrivateHeaders [ FDirName kernel ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
@@ -37,7 +40,6 @@ KernelStaticLibrary libkernelppp.a :
|
||||
KPPPReportManager.cpp
|
||||
KPPPStateMachine.cpp
|
||||
KPPPUtils.cpp
|
||||
Locker.cpp
|
||||
settings_tools.cpp
|
||||
|
||||
# integrated modules
|
||||
@@ -49,7 +51,5 @@ KernelStaticLibrary libkernelppp.a :
|
||||
|
||||
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||
SEARCH on [ FGristFiles Locker.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src system kernel disk_device_manager ] ;
|
||||
SEARCH on [ FGristFiles atomic.S ]
|
||||
= [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
This class allows iterating over configure items and adding/removing items.
|
||||
*/
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <net_buffer.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
#include <KPPPConfigurePacket.h>
|
||||
#include <KPPPInterface.h>
|
||||
|
||||
#include <core_funcs.h>
|
||||
|
||||
|
||||
/*! \brief Constructor.
|
||||
|
||||
@@ -27,18 +29,21 @@ KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
|
||||
|
||||
|
||||
//! Decodes a packet and adds its items to this object.
|
||||
KPPPConfigurePacket::KPPPConfigurePacket(struct mbuf *packet)
|
||||
KPPPConfigurePacket::KPPPConfigurePacket(net_buffer *packet)
|
||||
{
|
||||
// decode packet
|
||||
ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferhead(packet);
|
||||
if (bufferhead.Status() != B_OK)
|
||||
return;
|
||||
ppp_lcp_packet &header = bufferhead.Data();
|
||||
|
||||
SetID(header->id);
|
||||
if (!SetCode(header->code))
|
||||
SetID(header.id);
|
||||
if (!SetCode(header.code))
|
||||
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;
|
||||
// there are no items (or one corrupted item)
|
||||
|
||||
@@ -46,7 +51,7 @@ KPPPConfigurePacket::KPPPConfigurePacket(struct mbuf *packet)
|
||||
ppp_configure_item *item;
|
||||
|
||||
while (position < length - 4) {
|
||||
item = (ppp_configure_item*) (header->data + position);
|
||||
item = (ppp_configure_item*) (header.data + position);
|
||||
if (item->length < 2)
|
||||
return;
|
||||
// found a corrupted item
|
||||
@@ -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()!
|
||||
|
||||
\param MRU The interface's maximum receive unit (MRU).
|
||||
\param reserve Number of bytes to reserve at the beginning of the packet.
|
||||
|
||||
\return The mbuf structure or \c NULL on error (e.g.: too big for given MRU).
|
||||
\return The net_buffer structure or \c NULL on error (e.g.: too big for given MRU).
|
||||
*/
|
||||
struct mbuf*
|
||||
KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve)
|
||||
net_buffer*
|
||||
KPPPConfigurePacket::ToNetBuffer(uint32 MRU)
|
||||
{
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
packet->m_data += reserve;
|
||||
net_buffer *buffer = gBufferModule->create(256);
|
||||
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->id = ID();
|
||||
@@ -185,7 +199,7 @@ KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve)
|
||||
|
||||
// make sure we have enough space left
|
||||
if (MRU - length < item->length) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -195,7 +209,13 @@ KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve)
|
||||
|
||||
length += 4;
|
||||
header->length = htons(length);
|
||||
packet->m_pkthdr.len = packet->m_len = length;
|
||||
|
||||
return packet;
|
||||
status = gBufferModule->trim(buffer, length);
|
||||
if (status < B_OK) {
|
||||
dprintf("%s::%s: gBufferModule->trim\n", __FILE__, __func__);
|
||||
gBufferModule->free(buffer);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <KPPPDevice.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <core_funcs.h>
|
||||
|
||||
#include <PPPControl.h>
|
||||
|
||||
@@ -52,6 +51,7 @@ KPPPDevice::~KPPPDevice()
|
||||
status_t
|
||||
KPPPDevice::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
dprintf("KPPPDevice::Control\n");
|
||||
switch (op) {
|
||||
case PPPC_GET_DEVICE_INFO:
|
||||
{
|
||||
@@ -89,7 +89,7 @@ KPPPDevice::IsAllowedToSend() const
|
||||
|
||||
//! This method is never used.
|
||||
status_t
|
||||
KPPPDevice::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
KPPPDevice::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
// let the interface handle the packet
|
||||
if (protocolNumber == 0)
|
||||
|
||||
@@ -23,7 +23,11 @@
|
||||
// void (KernelExport.h) and once with int (stdio.h).
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <core_funcs.h>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <net_buffer.h>
|
||||
#include <net_stack.h>
|
||||
#include <ppp_device.h>
|
||||
|
||||
// now our headers...
|
||||
#include <KPPPInterface.h>
|
||||
@@ -38,7 +42,8 @@
|
||||
#include <KPPPUtils.h>
|
||||
|
||||
// general helper classes not only belonging to us
|
||||
#include <LockerHelper.h>
|
||||
// #include <lock.h>
|
||||
// #include <util/AutoLock.h>
|
||||
|
||||
// tools only for us :)
|
||||
#include "settings_tools.h"
|
||||
@@ -62,6 +67,9 @@ typedef struct reconnect_info {
|
||||
uint32 delay;
|
||||
} reconnect_info;
|
||||
|
||||
extern net_buffer_module_info *gBufferModule;
|
||||
extern net_stack_module_info *gStackModule;
|
||||
|
||||
status_t reconnect_thread(void *data);
|
||||
|
||||
// other functions
|
||||
@@ -95,7 +103,7 @@ KPPPInterface::KPPPInterface(const char *name, ppp_interface_entry *entry,
|
||||
fParent(NULL),
|
||||
fIsMultilink(false),
|
||||
fAutoReconnect(false),
|
||||
fConnectOnDemand(false),
|
||||
fConnectOnDemand(true),
|
||||
fAskBeforeConnecting(false),
|
||||
fMode(PPP_CLIENT_MODE),
|
||||
fLocalPFCState(PPP_PFC_DISABLED),
|
||||
@@ -250,10 +258,11 @@ KPPPInterface::~KPPPInterface()
|
||||
// This lock is not released until we are actually deleted.
|
||||
while (true) {
|
||||
Down();
|
||||
fLock.Lock();
|
||||
{
|
||||
MutexLocker (fLock);
|
||||
if (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)
|
||||
break;
|
||||
fLock.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
Report(PPP_DESTRUCTION_REPORT, 0, &fID, sizeof(ppp_interface_id));
|
||||
@@ -296,7 +305,9 @@ KPPPInterface::~KPPPInterface()
|
||||
void
|
||||
KPPPInterface::Delete()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
// MutexLocker locker(fLock);
|
||||
// alreay locked in KPPPStatemachine::DownEvent
|
||||
// uncomment this line will cause double lock
|
||||
|
||||
if (fDeleteCounter > 0)
|
||||
return;
|
||||
@@ -364,7 +375,9 @@ KPPPInterface::SetMRU(uint32 MRU)
|
||||
if (Device() && MRU > Device()->MTU() - 2)
|
||||
return false;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
// MutexLocker locker(fLock);
|
||||
// uncomment this line will cause double lock
|
||||
// alreay locked in ::Up and ::KPPPInterface
|
||||
|
||||
fMRU = MRU;
|
||||
|
||||
@@ -406,7 +419,298 @@ KPPPInterface::PacketOverhead() const
|
||||
status_t
|
||||
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:
|
||||
{
|
||||
if (length < sizeof(ppp_interface_info_t) || !data)
|
||||
@@ -417,7 +721,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
if (Name())
|
||||
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
|
||||
if (Ifnet())
|
||||
info->if_unit = Ifnet()->if_unit;
|
||||
info->if_unit = Ifnet()->index;
|
||||
else
|
||||
info->if_unit = -1;
|
||||
info->mode = Mode();
|
||||
@@ -456,7 +760,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
if (!data)
|
||||
return B_ERROR;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
// login information can only be changed before we authenticate
|
||||
if (Phase() >= PPP_AUTHENTICATION_PHASE)
|
||||
return B_NOT_ALLOWED;
|
||||
@@ -471,7 +775,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
if (!data)
|
||||
return B_ERROR;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
// login information can only be changed before we authenticate
|
||||
if (Phase() >= PPP_AUTHENTICATION_PHASE)
|
||||
return B_NOT_ALLOWED;
|
||||
@@ -524,7 +828,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
if (length < sizeof(ppp_report_request) || !data)
|
||||
return B_ERROR;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
ppp_report_request *request = (ppp_report_request*) data;
|
||||
// first, we send an initial state report
|
||||
if (request->type == PPP_CONNECTION_REPORT) {
|
||||
@@ -625,6 +929,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
|
||||
}
|
||||
|
||||
default:
|
||||
dprintf("bad ppp_interface_control!\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
@@ -656,7 +961,7 @@ KPPPInterface::SetDevice(KPPPDevice *device)
|
||||
return false;
|
||||
// main interfaces do not have devices
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
if (Phase() != PPP_DOWN_PHASE)
|
||||
return false;
|
||||
@@ -704,7 +1009,7 @@ KPPPInterface::AddProtocol(KPPPProtocol *protocol)
|
||||
|| protocol->Level() == PPP_INTERFACE_LEVEL)
|
||||
return false;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
if (Phase() != PPP_DOWN_PHASE)
|
||||
return false;
|
||||
@@ -768,7 +1073,7 @@ KPPPInterface::RemoveProtocol(KPPPProtocol *protocol)
|
||||
TRACE("KPPPInterface: RemoveProtocol(%X)\n",
|
||||
protocol ? protocol->ProtocolNumber() : 0);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
if (Phase() != PPP_DOWN_PHASE)
|
||||
return false;
|
||||
@@ -809,7 +1114,7 @@ KPPPInterface::RemoveProtocol(KPPPProtocol *protocol)
|
||||
int32
|
||||
KPPPInterface::CountProtocols() const
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
KPPPProtocol *protocol = FirstProtocol();
|
||||
|
||||
@@ -825,7 +1130,7 @@ KPPPInterface::CountProtocols() const
|
||||
KPPPProtocol*
|
||||
KPPPInterface::ProtocolAt(int32 index) const
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
KPPPProtocol *protocol = FirstProtocol();
|
||||
|
||||
@@ -849,7 +1154,8 @@ KPPPInterface::ProtocolFor(uint16 protocolNumber, KPPPProtocol *start) const
|
||||
{
|
||||
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();
|
||||
|
||||
@@ -874,7 +1180,7 @@ KPPPInterface::AddChild(KPPPInterface *child)
|
||||
if (!child)
|
||||
return false;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
if (fChildren.HasItem(child) || !fChildren.AddItem(child))
|
||||
return false;
|
||||
@@ -891,7 +1197,7 @@ KPPPInterface::RemoveChild(KPPPInterface *child)
|
||||
{
|
||||
TRACE("KPPPInterface: RemoveChild(%lX)\n", child ? child->ID() : 0);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
if (!fChildren.RemoveItem(child))
|
||||
return false;
|
||||
@@ -912,7 +1218,7 @@ KPPPInterface::ChildAt(int32 index) const
|
||||
{
|
||||
TRACE("KPPPInterface: ChildAt(%ld)\n", index);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
KPPPInterface *child = fChildren.ItemAt(index);
|
||||
|
||||
@@ -945,7 +1251,7 @@ KPPPInterface::SetConnectOnDemand(bool connectOnDemand)
|
||||
|
||||
TRACE("KPPPInterface: SetConnectOnDemand(%s)\n", connectOnDemand ? "true" : "false");
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
// Only clients support ConnectOnDemand.
|
||||
if (Mode() != PPP_CLIENT_MODE) {
|
||||
@@ -973,10 +1279,10 @@ KPPPInterface::SetConnectOnDemand(bool connectOnDemand)
|
||||
// check if we need to set/unset flags
|
||||
if (connectOnDemand) {
|
||||
if (Ifnet())
|
||||
Ifnet()->if_flags |= IFF_UP;
|
||||
Ifnet()->flags |= IFF_UP;
|
||||
} else if (!connectOnDemand && Phase() < PPP_ESTABLISHED_PHASE) {
|
||||
if (Ifnet())
|
||||
Ifnet()->if_flags &= ~IFF_UP;
|
||||
Ifnet()->flags &= ~IFF_UP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -985,14 +1291,14 @@ KPPPInterface::SetConnectOnDemand(bool connectOnDemand)
|
||||
void
|
||||
KPPPInterface::SetAskBeforeConnecting(bool ask)
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
bool old = fAskBeforeConnecting;
|
||||
fAskBeforeConnecting = ask;
|
||||
|
||||
if (old && fAskBeforeConnecting == false && State() == PPP_STARTING_STATE
|
||||
&& Phase() == PPP_DOWN_PHASE) {
|
||||
locker.UnlockNow();
|
||||
// locker.Unlock();
|
||||
StateMachine().ContinueOpenEvent();
|
||||
}
|
||||
}
|
||||
@@ -1004,7 +1310,7 @@ KPPPInterface::SetPFCOptions(uint8 pfcOptions)
|
||||
{
|
||||
TRACE("KPPPInterface: SetPFCOptions(0x%X)\n", pfcOptions);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
if (PFCOptions() & PPP_FREEZE_PFC_OPTIONS)
|
||||
return false;
|
||||
@@ -1032,7 +1338,7 @@ KPPPInterface::Up()
|
||||
if (IsUp())
|
||||
return true;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
StateMachine().OpenEvent();
|
||||
|
||||
return true;
|
||||
@@ -1059,7 +1365,7 @@ KPPPInterface::Down()
|
||||
send_data_with_timeout(fReconnectThread, 0, NULL, 0, 200);
|
||||
// tell the reconnect thread to abort its attempt (if it's still waiting)
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
StateMachine().CloseEvent();
|
||||
|
||||
return true;
|
||||
@@ -1075,6 +1381,12 @@ KPPPInterface::WaitForConnection()
|
||||
if (InitCheck() != B_OK)
|
||||
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));
|
||||
|
||||
ppp_report_packet report;
|
||||
@@ -1097,6 +1409,7 @@ KPPPInterface::WaitForConnection()
|
||||
}
|
||||
|
||||
ReportManager().DisableReports(PPP_CONNECTION_REPORT, find_thread(NULL));
|
||||
dprintf("KPPPInterface: WaitForConnection():%s\n", successful ? "True" : "False");
|
||||
return successful;
|
||||
}
|
||||
|
||||
@@ -1233,7 +1546,7 @@ KPPPInterface::IsAllowedToSend() const
|
||||
- \c B_ERROR: Some error occured.
|
||||
*/
|
||||
status_t
|
||||
KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
KPPPInterface::Send(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
TRACE("KPPPInterface: Send(0x%X)\n", protocolNumber);
|
||||
|
||||
@@ -1244,18 +1557,21 @@ KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
// do we have a device?
|
||||
// did we load all modules?
|
||||
if (InitCheck() != B_OK) {
|
||||
m_freem(packet);
|
||||
ERROR("InitCheck() fail\n");
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// go up if ConnectOnDemand is enabled and we are disconnected
|
||||
// TODO: our new netstack will simplify ConnectOnDemand handling, so
|
||||
// we do not have to handle it here
|
||||
if ((protocolNumber != PPP_LCP_PROTOCOL && DoesConnectOnDemand()
|
||||
&& (Phase() == PPP_DOWN_PHASE
|
||||
|| Phase() == PPP_ESTABLISHMENT_PHASE)
|
||||
&& !Up()) || !WaitForConnection()) {
|
||||
m_freem(packet);
|
||||
&& !Up()) && !WaitForConnection()) {
|
||||
dprintf("DoesConnectOnDemand fail!\n");
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -1279,52 +1595,61 @@ KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
#endif
|
||||
|
||||
// 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)) {
|
||||
ERROR("KPPPInterface::Send(): cannot send!\n");
|
||||
m_freem(packet);
|
||||
ERROR("KPPPInterface::Send(): Device is down, throw packet away!!\n");
|
||||
// gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// encode in ppp frame and consider using PFC
|
||||
if (UseLocalPFC() && protocolNumber & 0xFF00 == 0) {
|
||||
M_PREPEND(packet, 1);
|
||||
if (UseLocalPFC() && (protocolNumber & 0xFF00) == 0) {
|
||||
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)
|
||||
return B_ERROR;
|
||||
uint8 &header = bufferHeader.Data();
|
||||
|
||||
// memcpy(header.destination, ether_pppoe_ppp_header, 1);
|
||||
header = (protocolNumber & 0x00FF);
|
||||
// bufferHeader.Sync();
|
||||
|
||||
uint8 *header = mtod(packet, uint8*);
|
||||
*header = protocolNumber & 0xFF;
|
||||
} else {
|
||||
M_PREPEND(packet, 2);
|
||||
NetBufferPrepend<uint16> bufferHeader(packet);
|
||||
if (bufferHeader.Status() != B_OK)
|
||||
return bufferHeader.Status();
|
||||
|
||||
if (packet == NULL)
|
||||
return B_ERROR;
|
||||
uint16 &header = bufferHeader.Data();
|
||||
|
||||
// set protocol (the only header field)
|
||||
protocolNumber = htons(protocolNumber);
|
||||
uint16 *header = mtod(packet, uint16*);
|
||||
*header = protocolNumber;
|
||||
header = htons(protocolNumber);
|
||||
// bufferHeader.Sync();
|
||||
}
|
||||
|
||||
// pass to device if we're either not a multilink interface or a child interface
|
||||
if (!IsMultilink() || Parent()) {
|
||||
// check if packet is too big for device
|
||||
uint32 length = packet->m_flags & M_PKTHDR ? (uint32) packet->m_pkthdr.len :
|
||||
packet->m_len;
|
||||
uint32 length = packet->size;
|
||||
|
||||
if (length > MRU()) {
|
||||
m_freem(packet);
|
||||
dprintf("packet too large!\n");
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
atomic_add64(&fStatistics.bytesSent, length);
|
||||
atomic_add64(&fStatistics.packetsSent, 1);
|
||||
TRACE("%s::%s SendToNext\n", __FILE__, __func__);
|
||||
return SendToNext(packet, 0);
|
||||
// this is normally the device, but there can be something inbetween
|
||||
} else {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -1348,25 +1673,37 @@ KPPPInterface::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
- \c PPP_DISCARDED: The protocol handler(s) did not handle this packet.
|
||||
*/
|
||||
status_t
|
||||
KPPPInterface::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
KPPPInterface::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
TRACE("KPPPInterface: Receive(0x%X)\n", protocolNumber);
|
||||
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
int32 result = PPP_REJECTED;
|
||||
// assume we have no handler
|
||||
|
||||
// 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();
|
||||
if (protocolNumber == 0x0021 && Device() && Device()->IsUp()) {
|
||||
// IP_PROTOCOL 0x0021
|
||||
TRACE("%s::%s: receiving IP packet\n", __FILE__, __func__);
|
||||
ppp_device* dev=(ppp_device*)Ifnet();
|
||||
|
||||
if (dev)
|
||||
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.
|
||||
// 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);
|
||||
|
||||
if (result == PPP_UNHANDLED) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return PPP_DISCARDED;
|
||||
} else {
|
||||
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.
|
||||
*/
|
||||
status_t
|
||||
KPPPInterface::ReceiveFromDevice(struct mbuf *packet)
|
||||
KPPPInterface::ReceiveFromDevice(net_buffer *packet)
|
||||
{
|
||||
TRACE("KPPPInterface: ReceiveFromDevice()\n");
|
||||
|
||||
@@ -1427,20 +1764,37 @@ KPPPInterface::ReceiveFromDevice(struct mbuf *packet)
|
||||
return B_ERROR;
|
||||
|
||||
if (InitCheck() != B_OK) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
uint32 length = packet->m_flags & M_PKTHDR ? (uint32) packet->m_pkthdr.len :
|
||||
packet->m_len;
|
||||
|
||||
uint32 length = packet->size;
|
||||
// decode ppp frame and recognize PFC
|
||||
uint16 protocolNumber = *mtod(packet, uint8*);
|
||||
if (protocolNumber & 1) {
|
||||
m_adj(packet, 1);
|
||||
NetBufferHeaderReader<uint16> bufferHeader(packet);
|
||||
if (bufferHeader.Status() < B_OK)
|
||||
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 {
|
||||
protocolNumber = ntohs(*mtod(packet, uint16*));
|
||||
m_adj(packet, 2);
|
||||
TRACE("%s::%s:Non-PFC protocol:%x\n", __FILE__, __func__, protocolNumber);
|
||||
}
|
||||
|
||||
atomic_add64(&fStatistics.bytesReceived, length);
|
||||
@@ -1453,7 +1807,7 @@ KPPPInterface::ReceiveFromDevice(struct mbuf *packet)
|
||||
void
|
||||
KPPPInterface::Pulse()
|
||||
{
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
if (Device())
|
||||
Device()->Pulse();
|
||||
@@ -1485,7 +1839,7 @@ KPPPInterface::RegisterInterface()
|
||||
return true;
|
||||
// we are already registered
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
// only MainInterfaces get an ifnet
|
||||
if (IsMultilink() && Parent() && Parent()->RegisterInterface())
|
||||
@@ -1496,11 +1850,13 @@ KPPPInterface::RegisterInterface()
|
||||
|
||||
fIfnet = fManager->RegisterInterface(ID());
|
||||
|
||||
if (!fIfnet)
|
||||
if (!fIfnet) {
|
||||
dprintf("%s:%s: damn it no fIfnet device\n", __FILE__, __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DoesConnectOnDemand())
|
||||
fIfnet->if_flags |= IFF_UP;
|
||||
fIfnet->flags |= IFF_UP;
|
||||
|
||||
CalculateInterfaceMTU();
|
||||
CalculateBaudRate();
|
||||
@@ -1519,7 +1875,7 @@ KPPPInterface::UnregisterInterface()
|
||||
return true;
|
||||
// we are already unregistered
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
// only MainInterfaces get an ifnet
|
||||
if (IsMultilink() && Parent())
|
||||
@@ -1587,7 +1943,7 @@ KPPPInterface::StackControlEachHandler(uint32 op, void *data)
|
||||
|
||||
status_t result = B_BAD_VALUE, tmp;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
KPPPProtocol *protocol = FirstProtocol();
|
||||
for (; protocol; protocol = protocol->NextProtocol()) {
|
||||
@@ -1613,7 +1969,9 @@ KPPPInterface::CalculateInterfaceMTU()
|
||||
{
|
||||
TRACE("KPPPInterface: CalculateInterfaceMTU()\n");
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
// MutexLocker locker(fLock);
|
||||
// uncomment this line will cause double lock
|
||||
// alreay locked in ::KPPPInterface
|
||||
|
||||
fInterfaceMTU = fMRU;
|
||||
fHeaderLength = 2;
|
||||
@@ -1628,8 +1986,9 @@ KPPPInterface::CalculateInterfaceMTU()
|
||||
fInterfaceMTU -= fHeaderLength;
|
||||
|
||||
if (Ifnet()) {
|
||||
Ifnet()->if_mtu = fInterfaceMTU;
|
||||
Ifnet()->if_hdrlen = fHeaderLength;
|
||||
Ifnet()->mtu = fInterfaceMTU;
|
||||
Ifnet()->header_length = fHeaderLength;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Parent())
|
||||
@@ -1643,19 +2002,20 @@ KPPPInterface::CalculateBaudRate()
|
||||
{
|
||||
TRACE("KPPPInterface: CalculateBaudRate()\n");
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
// MutexLocker locker(fLock); // uncomment this will cause double lock
|
||||
|
||||
if (!Ifnet())
|
||||
return;
|
||||
|
||||
if (Device())
|
||||
fIfnet->if_baudrate = max_c(Device()->InputTransferRate(),
|
||||
fIfnet->link_speed = max_c(Device()->InputTransferRate(),
|
||||
Device()->OutputTransferRate());
|
||||
else {
|
||||
fIfnet->if_baudrate = 0;
|
||||
fIfnet->link_speed = 0;
|
||||
for (int32 index = 0; index < CountChildren(); index++)
|
||||
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);
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
if (fReconnectThread != -1)
|
||||
return;
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
#include <KPPPOptionHandler.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <core_funcs.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
extern net_buffer_module_info *gBufferModule;
|
||||
|
||||
|
||||
//! Creates a new LCP protocol for the given interface.
|
||||
KPPPLCP::KPPPLCP(KPPPInterface& interface)
|
||||
@@ -87,6 +90,7 @@ KPPPLCP::RemoveOptionHandler(KPPPOptionHandler *optionHandler)
|
||||
KPPPOptionHandler*
|
||||
KPPPLCP::OptionHandlerAt(int32 index) const
|
||||
{
|
||||
dprintf("total optionhandler count %ld\n", CountOptionHandlers());
|
||||
KPPPOptionHandler *optionHandler = fOptionHandlers.ItemAt(index);
|
||||
|
||||
if (optionHandler == fOptionHandlers.GetDefaultItem())
|
||||
@@ -160,6 +164,7 @@ KPPPLCP::RemoveLCPExtension(KPPPLCPExtension *lcpExtension)
|
||||
KPPPLCPExtension*
|
||||
KPPPLCP::LCPExtensionAt(int32 index) const
|
||||
{
|
||||
dprintf("LCPExtension count %ld\n", CountLCPExtensions());
|
||||
KPPPLCPExtension *lcpExtension = fLCPExtensions.ItemAt(index);
|
||||
|
||||
if (lcpExtension == fLCPExtensions.GetDefaultItem())
|
||||
@@ -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.
|
||||
bool
|
||||
KPPPLCP::Up()
|
||||
@@ -230,7 +219,7 @@ KPPPLCP::Down()
|
||||
|
||||
//! Sends a packet to the target (if there is one) or to the interface.
|
||||
status_t
|
||||
KPPPLCP::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
KPPPLCP::Send(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
if (Target())
|
||||
return Target()->Send(packet, PPP_LCP_PROTOCOL);
|
||||
@@ -241,7 +230,7 @@ KPPPLCP::Send(struct mbuf *packet, uint16 protocolNumber)
|
||||
|
||||
//! Decodes the LCP packet and passes it to the KPPPStateMachine or an LCP extension.
|
||||
status_t
|
||||
KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
KPPPLCP::Receive(net_buffer *packet, uint16 protocolNumber)
|
||||
{
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
@@ -251,29 +240,22 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
return PPP_UNHANDLED;
|
||||
}
|
||||
|
||||
ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||
if (bufferHeader.Status() < B_OK)
|
||||
return bufferHeader.Status();
|
||||
|
||||
ppp_lcp_packet &data = bufferHeader.Data();
|
||||
|
||||
// remove padding
|
||||
int32 length = packet->m_len;
|
||||
if (packet->m_flags & M_PKTHDR)
|
||||
length = packet->m_pkthdr.len;
|
||||
length -= ntohs(data->length);
|
||||
if (length)
|
||||
m_adj(packet, -length);
|
||||
|
||||
struct mbuf *copy = m_gethdr(MT_DATA);
|
||||
if (copy) {
|
||||
copy->m_data += AdditionalOverhead();
|
||||
copy->m_pkthdr.len = copy->m_len = packet->m_len;
|
||||
memcpy(copy->m_data, packet->m_data, copy->m_len);
|
||||
}
|
||||
net_buffer *copy = gBufferModule->duplicate(packet);
|
||||
|
||||
if (ntohs(data->length) < 4)
|
||||
if (ntohs(data.length) < 4)
|
||||
return B_ERROR;
|
||||
|
||||
bool handled = true;
|
||||
|
||||
switch (data->code) {
|
||||
switch (data.code) {
|
||||
case PPP_CONFIGURE_REQUEST:
|
||||
StateMachine().RCREvent(packet);
|
||||
break;
|
||||
@@ -310,7 +292,7 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
break;
|
||||
|
||||
default:
|
||||
m_freem(packet);
|
||||
// gBufferModule->free(packet);
|
||||
handled = false;
|
||||
}
|
||||
|
||||
@@ -324,18 +306,18 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
// Try to find LCP extensions that can handle this code.
|
||||
// We must duplicate the packet in order to ask all handlers.
|
||||
int32 index = 0;
|
||||
KPPPLCPExtension *lcpExtension = LCPExtensionFor(data->code, &index);
|
||||
for (; lcpExtension; lcpExtension = LCPExtensionFor(data->code, &(++index))) {
|
||||
KPPPLCPExtension *lcpExtension = LCPExtensionFor(data.code, &index);
|
||||
for (; lcpExtension; lcpExtension = LCPExtensionFor(data.code, &(++index))) {
|
||||
if (!lcpExtension->IsEnabled())
|
||||
continue;
|
||||
|
||||
result = lcpExtension->Receive(packet, data->code);
|
||||
result = lcpExtension->Receive(packet, data.code);
|
||||
|
||||
// check return value and return it on error
|
||||
if (result == B_OK)
|
||||
handled = true;
|
||||
else if (result != PPP_UNHANDLED) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -345,7 +327,7 @@ KPPPLCP::Receive(struct mbuf *packet, uint16 protocolNumber)
|
||||
return PPP_REJECTED;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ KPPPLCPExtension::InitCheck() const
|
||||
status_t
|
||||
KPPPLCPExtension::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
dprintf("KPPPLCPExtension::Control\n");
|
||||
switch (op) {
|
||||
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||
{
|
||||
|
||||
@@ -19,10 +19,12 @@
|
||||
|
||||
#include <KPPPLayer.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <core_funcs.h>
|
||||
|
||||
extern net_buffer_module_info *gBufferModule;
|
||||
|
||||
/*! \brief Creates a new layer.
|
||||
|
||||
@@ -56,7 +58,7 @@ KPPPLayer::InitCheck() const
|
||||
|
||||
//! Sends a packet to the next layer in the chain.
|
||||
status_t
|
||||
KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
|
||||
KPPPLayer::SendToNext(net_buffer *packet, uint16 protocolNumber) const
|
||||
{
|
||||
if (!packet)
|
||||
return B_ERROR;
|
||||
@@ -70,7 +72,7 @@ KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
|
||||
return Next()->SendToNext(packet, protocolNumber);
|
||||
} else {
|
||||
ERROR("KPPPLayer: SendToNext() failed because there is no next handler!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ KPPPOptionHandler::InitCheck() const
|
||||
status_t
|
||||
KPPPOptionHandler::Control(uint32 op, void *data, size_t length)
|
||||
{
|
||||
dprintf("KPPPOptionHandler::Control\n");
|
||||
switch (op) {
|
||||
case PPPC_GET_SIMPLE_HANDLER_INFO:
|
||||
{
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
#include <KPPPReportManager.h>
|
||||
|
||||
#include <LockerHelper.h>
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
#include <KPPPUtils.h>
|
||||
|
||||
|
||||
@@ -33,7 +35,7 @@ report_sender_thread(void *data)
|
||||
|
||||
\param lock The BLocker that should be used by this report manager.
|
||||
*/
|
||||
KPPPReportManager::KPPPReportManager(BLocker& lock)
|
||||
KPPPReportManager::KPPPReportManager(mutex& lock)
|
||||
: fLock(lock)
|
||||
{
|
||||
}
|
||||
@@ -88,7 +90,7 @@ KPPPReportManager::EnableReports(ppp_report_type type, thread_id thread,
|
||||
if (thread < 0 || type == PPP_ALL_REPORTS)
|
||||
return;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
ppp_report_request *request = new ppp_report_request;
|
||||
request->type = type;
|
||||
@@ -106,7 +108,7 @@ KPPPReportManager::DisableReports(ppp_report_type type, thread_id thread)
|
||||
if (thread < 0)
|
||||
return;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
ppp_report_request *request;
|
||||
|
||||
@@ -135,7 +137,7 @@ KPPPReportManager::DoesReport(ppp_report_type type, thread_id thread)
|
||||
if (thread < 0)
|
||||
return false;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
ppp_report_request *request;
|
||||
|
||||
@@ -177,7 +179,7 @@ KPPPReportManager::Report(ppp_report_type type, int32 code, void *data, int32 le
|
||||
if (!data)
|
||||
length = 0;
|
||||
|
||||
LockerHelper locker(fLock);
|
||||
MutexLocker locker(fLock);
|
||||
|
||||
status_t result;
|
||||
thread_id me = find_thread(NULL);
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
#include <KPPPUtils.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;
|
||||
// 3 seconds
|
||||
@@ -49,8 +53,9 @@ KPPPStateMachine::KPPPStateMachine(KPPPInterface& interface)
|
||||
fTerminateID(0),
|
||||
fEchoID(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.
|
||||
if (Phase() == PPP_ESTABLISHED_PHASE && next != Phase()) {
|
||||
if (Interface().Ifnet()) {
|
||||
Interface().Ifnet()->if_flags &= ~IFF_RUNNING;
|
||||
Interface().Ifnet()->if_flags &= ~IFF_UP;
|
||||
// Interface().Ifnet()->flags &= ~IFF_RUNNING;
|
||||
Interface().Ifnet()->flags &= ~IFF_UP;
|
||||
}
|
||||
|
||||
if (Interface().Parent())
|
||||
@@ -128,7 +133,7 @@ KPPPStateMachine::NewPhase(ppp_phase next)
|
||||
Interface().fConnectedSince = system_time();
|
||||
|
||||
if (Interface().Ifnet())
|
||||
Interface().Ifnet()->if_flags |= IFF_UP | IFF_RUNNING;
|
||||
Interface().Ifnet()->flags |= IFF_UP;// | IFF_RUNNING;
|
||||
|
||||
Interface().fConnectAttempt = 0;
|
||||
// when we Reconnect() this becomes 1 (the first connection attempt)
|
||||
@@ -172,20 +177,32 @@ KPPPStateMachine::SendEchoRequest()
|
||||
if (State() != PPP_OPENED_STATE)
|
||||
return false;
|
||||
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
if (!packet)
|
||||
net_buffer *packet = gBufferModule->create(256);
|
||||
if (packet == NULL)
|
||||
return false;
|
||||
|
||||
packet->m_data += LCP().AdditionalOverhead();
|
||||
packet->m_pkthdr.len = packet->m_len = 8;
|
||||
// echo requests are at least eight bytes long
|
||||
void *data;
|
||||
status_t status = gBufferModule->append_size(packet, 1492, &data);
|
||||
if (status == B_OK && data == NULL) {
|
||||
gBufferModule->free(packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
||||
request->code = PPP_ECHO_REQUEST;
|
||||
request->id = NextID();
|
||||
fEchoID = request->id;
|
||||
request->length = htons(packet->m_len);
|
||||
memcpy(request->data, &fMagicNumber, sizeof(fMagicNumber));
|
||||
// echo requests are at least eight bytes long
|
||||
ppp_lcp_packet request;
|
||||
request.code = PPP_ECHO_REQUEST;
|
||||
request.id = NextID();
|
||||
request.length = htons(8);
|
||||
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;
|
||||
}
|
||||
@@ -197,22 +214,33 @@ KPPPStateMachine::SendDiscardRequest()
|
||||
{
|
||||
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;
|
||||
|
||||
struct mbuf *packet = m_gethdr(MT_DATA);
|
||||
if (!packet)
|
||||
void *data;
|
||||
status_t status = gBufferModule->append_size(packet, 1492, &data);
|
||||
if (status == B_OK && data == NULL) {
|
||||
gBufferModule->free(packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
packet->m_data += LCP().AdditionalOverhead();
|
||||
packet->m_pkthdr.len = packet->m_len = 8;
|
||||
// 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*);
|
||||
request->code = PPP_DISCARD_REQUEST;
|
||||
request->id = NextID();
|
||||
request->length = htons(packet->m_len);
|
||||
memcpy(request->data, &fMagicNumber, sizeof(fMagicNumber));
|
||||
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;
|
||||
}
|
||||
@@ -893,42 +921,49 @@ KPPPStateMachine::TOBadEvent()
|
||||
|
||||
// receive configure request (acceptable request)
|
||||
void
|
||||
KPPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RCRGoodEvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("KPPPSM: RCRGoodEvent() state=%d phase=%d\n", State(), Phase());
|
||||
|
||||
switch (State()) {
|
||||
case PPP_INITIAL_STATE:
|
||||
case PPP_STARTING_STATE:
|
||||
TRACE("%s::%s: PPP_STARTING_STATE\n", __FILE__, __func__);
|
||||
IllegalEvent(PPP_RCR_GOOD_EVENT);
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
break;
|
||||
|
||||
case PPP_CLOSED_STATE:
|
||||
TRACE("%s::%s: PPP_CLOSED_STATE\n", __FILE__, __func__);
|
||||
SendTerminateAck();
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
break;
|
||||
|
||||
case PPP_STOPPED_STATE:
|
||||
TRACE("%s::%s: PPP_STOPPED_STATE\n", __FILE__, __func__);
|
||||
// irc,scr,sca/8
|
||||
// XXX: should we do nothing and wait for DownEvent()?
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
break;
|
||||
|
||||
case PPP_REQ_SENT_STATE:
|
||||
NewState(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);
|
||||
break;
|
||||
|
||||
case PPP_ACK_RCVD_STATE:
|
||||
TRACE("%s::%s: PPP_ACK_RCVD_STATE\n", __FILE__, __func__);
|
||||
NewState(PPP_OPENED_STATE);
|
||||
SendConfigureAck(packet);
|
||||
ThisLayerUp();
|
||||
break;
|
||||
|
||||
case PPP_OPENED_STATE:
|
||||
TRACE("%s::%s: PPP_OPENED_STATE\n", __FILE__, __func__);
|
||||
NewState(PPP_ACK_SENT_STATE);
|
||||
NewPhase(PPP_ESTABLISHMENT_PHASE);
|
||||
// indicates to handlers that we are reconfiguring
|
||||
@@ -938,17 +973,21 @@ KPPPStateMachine::RCRGoodEvent(struct mbuf *packet)
|
||||
break;
|
||||
|
||||
default:
|
||||
m_freem(packet);
|
||||
TRACE("free peer's ppp request packet\n");
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// receive configure request (unacceptable request)
|
||||
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());
|
||||
|
||||
uint16 lenNak = 0;
|
||||
uint16 lenReject = 0;
|
||||
|
||||
switch (State()) {
|
||||
case PPP_INITIAL_STATE:
|
||||
case PPP_STARTING_STATE:
|
||||
@@ -978,9 +1017,25 @@ KPPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
||||
|
||||
case PPP_REQ_SENT_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);
|
||||
else if (reject && ntohs(mtod(reject, ppp_lcp_packet*)->length) > 3)
|
||||
else if (reject && lenReject > 3)
|
||||
SendConfigureNak(reject);
|
||||
return;
|
||||
// prevents the nak/reject from being m_freem()'d
|
||||
@@ -990,24 +1045,29 @@ KPPPStateMachine::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
|
||||
}
|
||||
|
||||
if (nak)
|
||||
m_freem(nak);
|
||||
gBufferModule->free(nak);
|
||||
if (reject)
|
||||
m_freem(reject);
|
||||
gBufferModule->free(reject);
|
||||
}
|
||||
|
||||
|
||||
// receive configure ack
|
||||
void
|
||||
KPPPStateMachine::RCAEvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RCAEvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
|
||||
// TODO:
|
||||
// log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1017,7 +1077,7 @@ KPPPStateMachine::RCAEvent(struct mbuf *packet)
|
||||
for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
optionHandler = LCP().OptionHandlerAt(index);
|
||||
if (optionHandler->ParseAck(ack) != B_OK) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
@@ -1062,22 +1122,27 @@ KPPPStateMachine::RCAEvent(struct mbuf *packet)
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
// receive configure nak/reject
|
||||
void
|
||||
KPPPStateMachine::RCNEvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RCNEvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
|
||||
// TODO:
|
||||
// log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1089,13 +1154,13 @@ KPPPStateMachine::RCNEvent(struct mbuf *packet)
|
||||
|
||||
if (nak_reject.Code() == PPP_CONFIGURE_NAK) {
|
||||
if (optionHandler->ParseNak(nak_reject) != B_OK) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
} else if (nak_reject.Code() == PPP_CONFIGURE_REJECT) {
|
||||
if (optionHandler->ParseReject(nak_reject) != B_OK) {
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
@@ -1135,18 +1200,23 @@ KPPPStateMachine::RCNEvent(struct mbuf *packet)
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
// receive terminate request
|
||||
void
|
||||
KPPPStateMachine::RTREvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RTREvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
if (fID == mtod(packet, ppp_lcp_packet*)->id)
|
||||
if (fID == header.id)
|
||||
fID -= 128;
|
||||
|
||||
fLocalAuthenticationStatus = PPP_NOT_AUTHENTICATED;
|
||||
@@ -1156,7 +1226,7 @@ KPPPStateMachine::RTREvent(struct mbuf *packet)
|
||||
case PPP_INITIAL_STATE:
|
||||
case PPP_STARTING_STATE:
|
||||
IllegalEvent(PPP_RTR_EVENT);
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
break;
|
||||
|
||||
case PPP_ACK_RCVD_STATE:
|
||||
@@ -1186,16 +1256,21 @@ KPPPStateMachine::RTREvent(struct mbuf *packet)
|
||||
|
||||
// receive terminate ack
|
||||
void
|
||||
KPPPStateMachine::RTAEvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RTAEvent(net_buffer *packet)
|
||||
{
|
||||
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
|
||||
|
||||
// TODO:
|
||||
// log this event
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1231,13 +1306,13 @@ KPPPStateMachine::RTAEvent(struct mbuf *packet)
|
||||
;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
// receive unknown code
|
||||
void
|
||||
KPPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
||||
KPPPStateMachine::RUCEvent(net_buffer *packet, uint16 protocolNumber,
|
||||
uint8 code)
|
||||
{
|
||||
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_STARTING_STATE:
|
||||
IllegalEvent(PPP_RUC_EVENT);
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1257,7 +1332,7 @@ KPPPStateMachine::RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
||||
|
||||
// receive code/protocol reject (acceptable such as IPX reject)
|
||||
void
|
||||
KPPPStateMachine::RXJGoodEvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RXJGoodEvent(net_buffer *packet)
|
||||
{
|
||||
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)
|
||||
void
|
||||
KPPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RXJBadEvent(net_buffer *packet)
|
||||
{
|
||||
TRACE("KPPPSM: RXJBadEvent() state=%d phase=%d\n", State(), Phase());
|
||||
|
||||
@@ -1321,19 +1396,22 @@ KPPPStateMachine::RXJBadEvent(struct mbuf *packet)
|
||||
break;
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
|
||||
|
||||
// receive echo request/reply, discard request
|
||||
void
|
||||
KPPPStateMachine::RXREvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RXREvent(net_buffer *packet)
|
||||
{
|
||||
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:
|
||||
// log that we got a reply, but no request was sent
|
||||
}
|
||||
@@ -1345,7 +1423,7 @@ KPPPStateMachine::RXREvent(struct mbuf *packet)
|
||||
break;
|
||||
|
||||
case PPP_OPENED_STATE:
|
||||
if (echo->code == PPP_ECHO_REQUEST)
|
||||
if (echo.code == PPP_ECHO_REQUEST)
|
||||
SendEchoReply(packet);
|
||||
return;
|
||||
// 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
|
||||
// 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.
|
||||
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 nak(PPP_CONFIGURE_NAK);
|
||||
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
|
||||
if (fID == mtod(packet, ppp_lcp_packet*)->id)
|
||||
if (fID == header.id)
|
||||
fID -= 128;
|
||||
// or maybe we should use peer's ID plus 1 ?
|
||||
|
||||
nak.SetID(request.ID());
|
||||
reject.SetID(request.ID());
|
||||
@@ -1423,11 +1508,23 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
optionHandler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
|
||||
|
||||
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
|
||||
TRACE("why come here %ld\n", index);
|
||||
reject.AddItem(request.ItemAt(index));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("KPPPSM::RCREvent(): OH=%s\n",
|
||||
optionHandler->Name() ? optionHandler->Name() : "Unknown");
|
||||
@@ -1435,13 +1532,14 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
|
||||
if (result == PPP_UNHANDLED) {
|
||||
// unhandled items should be added to the reject
|
||||
TRACE("PPP_UNHANDLED %ld\n", index);
|
||||
reject.AddItem(request.ItemAt(index));
|
||||
continue;
|
||||
} else if (result != B_OK) {
|
||||
// the request contains a value that has been sent more than
|
||||
// once or the value is corrupted
|
||||
ERROR("KPPPSM::RCREvent(): OptionHandler returned parse error!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
@@ -1460,7 +1558,7 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
// the request contains a value that has been sent more than
|
||||
// once or the value is corrupted
|
||||
ERROR("KPPPSM::RCREvent():OptionHandler returned append error!\n");
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
CloseEvent();
|
||||
return;
|
||||
}
|
||||
@@ -1469,11 +1567,13 @@ KPPPStateMachine::RCREvent(struct mbuf *packet)
|
||||
}
|
||||
|
||||
if (reject.CountItems() > 0) {
|
||||
RCRBadEvent(NULL, reject.ToMbuf(Interface().MRU(), LCP().AdditionalOverhead()));
|
||||
m_freem(packet);
|
||||
TRACE("%s:reject number more than 0\n", __func__);
|
||||
RCRBadEvent(NULL, reject.ToNetBuffer(Interface().MRU()));
|
||||
gBufferModule->free(packet);
|
||||
} else if (nak.CountItems() > 0) {
|
||||
RCRBadEvent(nak.ToMbuf(Interface().MRU(), LCP().AdditionalOverhead()), NULL);
|
||||
m_freem(packet);
|
||||
TRACE("%s:nak number more than 0\n", __func__);
|
||||
RCRBadEvent(nak.ToNetBuffer(Interface().MRU()), NULL);
|
||||
gBufferModule->free(packet);
|
||||
} else
|
||||
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.
|
||||
// From here we call our Good/Bad counterparts.
|
||||
void
|
||||
KPPPStateMachine::RXJEvent(struct mbuf *packet)
|
||||
KPPPStateMachine::RXJEvent(net_buffer *packet)
|
||||
{
|
||||
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) {
|
||||
uint8 rejectedCode = reject->data[0];
|
||||
if (reject.code == PPP_CODE_REJECT) {
|
||||
uint8 rejectedCode = reject.data[0];
|
||||
|
||||
// test if the rejected code belongs to the minimum LCP requirements
|
||||
if (rejectedCode >= PPP_MIN_LCP_CODE && rejectedCode <= PPP_MAX_LCP_CODE) {
|
||||
if (Interface().IsMultilink() && !Interface().Parent()) {
|
||||
// Main interfaces do not have states between STARTING and OPENED.
|
||||
// An RXJBadEvent() would enter one of those states which is bad.
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
CloseEvent();
|
||||
} else
|
||||
RXJBadEvent(packet);
|
||||
@@ -1514,10 +1617,10 @@ KPPPStateMachine::RXJEvent(struct mbuf *packet)
|
||||
lcpExtension->SetEnabled(false);
|
||||
}
|
||||
|
||||
m_freem(packet);
|
||||
} else if (reject->code == PPP_PROTOCOL_REJECT) {
|
||||
gBufferModule->free(packet);
|
||||
} else if (reject.code == PPP_PROTOCOL_REJECT) {
|
||||
// disable all handlers for rejected protocol type
|
||||
uint16 rejected = *((uint16*) reject->data);
|
||||
uint16 rejected = *((uint16*) reject.data);
|
||||
// rejected protocol number
|
||||
|
||||
if (rejected == PPP_LCP_PROTOCOL) {
|
||||
@@ -1541,7 +1644,7 @@ KPPPStateMachine::RXJEvent(struct mbuf *packet)
|
||||
if (Interface().Parent())
|
||||
Interface().Parent()->StateMachine().RXJEvent(packet);
|
||||
else
|
||||
m_freem(packet);
|
||||
gBufferModule->free(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1552,7 +1655,7 @@ KPPPStateMachine::IllegalEvent(ppp_event event)
|
||||
{
|
||||
// TODO:
|
||||
// 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());
|
||||
}
|
||||
|
||||
@@ -1643,48 +1746,60 @@ KPPPStateMachine::SendConfigureRequest()
|
||||
}
|
||||
}
|
||||
|
||||
return LCP().Send(request.ToMbuf(Interface().MRU(),
|
||||
LCP().AdditionalOverhead())) == B_OK;
|
||||
return LCP().Send(request.ToNetBuffer(Interface().MRU())) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
KPPPStateMachine::SendConfigureAck(struct mbuf *packet)
|
||||
KPPPStateMachine::SendConfigureAck(net_buffer *packet)
|
||||
{
|
||||
TRACE("KPPPSM: SendConfigureAck() state=%d phase=%d\n", State(), Phase());
|
||||
|
||||
if (!packet)
|
||||
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);
|
||||
|
||||
// notify all option handlers that we are sending an ack for each value
|
||||
for (int32 index = 0; index < LCP().CountOptionHandlers(); index++) {
|
||||
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();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("%s::%s: LCP().Send\n", __FILE__, __func__);
|
||||
return LCP().Send(packet) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
KPPPStateMachine::SendConfigureNak(struct mbuf *packet)
|
||||
KPPPStateMachine::SendConfigureNak(net_buffer *packet)
|
||||
{
|
||||
TRACE("KPPPSM: SendConfigureNak() state=%d phase=%d\n", State(), Phase());
|
||||
|
||||
if (!packet)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
|
||||
if (nak->code == PPP_CONFIGURE_NAK) {
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||
if (bufferHeader.Status() < B_OK)
|
||||
return false;
|
||||
ppp_lcp_packet &nak = bufferHeader.Data();
|
||||
|
||||
if (nak.code == PPP_CONFIGURE_NAK) {
|
||||
if (fNakCounter == 0) {
|
||||
// We sent enough naks. Let's try a reject.
|
||||
nak->code = PPP_CONFIGURE_REJECT;
|
||||
nak.code = PPP_CONFIGURE_REJECT;
|
||||
} else
|
||||
--fNakCounter;
|
||||
}
|
||||
@@ -1701,55 +1816,60 @@ KPPPStateMachine::SendTerminateRequest()
|
||||
--fTerminateCounter;
|
||||
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)
|
||||
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
|
||||
packet->m_data += LCP().AdditionalOverhead();
|
||||
status = gBufferModule->trim(buffer, 4);
|
||||
if (status < B_OK) {
|
||||
gBufferModule->free(buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
|
||||
request->code = PPP_TERMINATE_REQUEST;
|
||||
request->id = fTerminateID = NextID();
|
||||
request->length = htons(4);
|
||||
|
||||
return LCP().Send(packet) == B_OK;
|
||||
return LCP().Send(buffer) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
KPPPStateMachine::SendTerminateAck(struct mbuf *request)
|
||||
KPPPStateMachine::SendTerminateAck(net_buffer *request)
|
||||
{
|
||||
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) {
|
||||
reply = m_gethdr(MT_DATA);
|
||||
if (!reply)
|
||||
return false;
|
||||
ack.length = htons(4);
|
||||
ack.id = NextID();
|
||||
}
|
||||
|
||||
reply->m_data += LCP().AdditionalOverhead();
|
||||
reply->m_pkthdr.len = reply->m_len = 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);
|
||||
ack.code = PPP_TERMINATE_ACK;
|
||||
ack.length = htons(4);
|
||||
|
||||
return LCP().Send(reply) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
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",
|
||||
protocolNumber, code, State(), Phase());
|
||||
@@ -1764,52 +1884,40 @@ KPPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uin
|
||||
else
|
||||
length = 4;
|
||||
|
||||
M_PREPEND(packet, length);
|
||||
// add some space for the header
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(packet);
|
||||
if (bufferHeader.Status() < B_OK)
|
||||
return false;
|
||||
ppp_lcp_packet &reject = bufferHeader.Data();
|
||||
|
||||
// adjust packet if too big
|
||||
int32 adjust = Interface().MRU();
|
||||
if (packet->m_flags & M_PKTHDR) {
|
||||
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);
|
||||
reject.code = code;
|
||||
reject.id = NextID();
|
||||
reject.length = htons(length);
|
||||
|
||||
protocolNumber = htons(protocolNumber);
|
||||
if (code == PPP_PROTOCOL_REJECT)
|
||||
memcpy(&reject->data, &protocolNumber, sizeof(protocolNumber));
|
||||
memcpy(&reject.data, &protocolNumber, sizeof(protocolNumber));
|
||||
|
||||
return LCP().Send(packet) == B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
KPPPStateMachine::SendEchoReply(struct mbuf *request)
|
||||
KPPPStateMachine::SendEchoReply(net_buffer *request)
|
||||
{
|
||||
TRACE("KPPPSM: SendEchoReply() state=%d phase=%d\n", State(), Phase());
|
||||
|
||||
if (!request)
|
||||
return false;
|
||||
|
||||
ppp_lcp_packet *reply = mtod(request, ppp_lcp_packet*);
|
||||
reply->code = PPP_ECHO_REPLY;
|
||||
NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(request);
|
||||
if (bufferHeader.Status() < B_OK)
|
||||
return false;
|
||||
ppp_lcp_packet &reply = bufferHeader.Data();
|
||||
|
||||
reply.code = PPP_ECHO_REPLY;
|
||||
// the request becomes a reply
|
||||
|
||||
if (request->m_flags & M_PKTHDR)
|
||||
request->m_pkthdr.len = 8;
|
||||
request->m_len = 8;
|
||||
|
||||
memcpy(reply->data, &fMagicNumber, sizeof(fMagicNumber));
|
||||
memcpy(reply.data, &fMagicNumber, sizeof(fMagicNumber));
|
||||
|
||||
return LCP().Send(request) == B_OK;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#define _K_PPP_CONFIGURE_PACKET__H
|
||||
|
||||
#include <TemplateList.h>
|
||||
|
||||
struct mbuf;
|
||||
#include <net_buffer.h>
|
||||
|
||||
//! An abstract configure item.
|
||||
typedef struct ppp_configure_item {
|
||||
@@ -29,7 +28,7 @@ class KPPPConfigurePacket {
|
||||
|
||||
public:
|
||||
KPPPConfigurePacket(uint8 code);
|
||||
KPPPConfigurePacket(struct mbuf *packet);
|
||||
KPPPConfigurePacket(net_buffer *packet);
|
||||
~KPPPConfigurePacket();
|
||||
|
||||
bool SetCode(uint8 code);
|
||||
@@ -52,8 +51,8 @@ class KPPPConfigurePacket {
|
||||
ppp_configure_item *ItemAt(int32 index) const;
|
||||
ppp_configure_item *ItemWithType(uint8 type) const;
|
||||
|
||||
struct mbuf *ToMbuf(uint32 MRU, uint32 reserve = 0);
|
||||
// the user is responsible for freeing the mbuf
|
||||
net_buffer *ToNetBuffer(uint32 MRU);
|
||||
// the user is responsible for freeing the net_buffer
|
||||
|
||||
private:
|
||||
uint8 fCode, fID;
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <KPPPDefs.h>
|
||||
#include <KPPPLayer.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
#ifndef _K_PPP_INTERFACE__H
|
||||
#include <KPPPInterface.h>
|
||||
#endif
|
||||
@@ -96,8 +98,8 @@ class KPPPDevice : public KPPPLayer {
|
||||
This should enqueue the packet and return immediately (never block).
|
||||
The device is responsible for freeing the packet by calling \c m_freem().
|
||||
*/
|
||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||
|
||||
protected:
|
||||
//! Use this to set the device's maximum transfer unit (in bytes).
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
|
||||
#include <TemplateList.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <net_device.h>
|
||||
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
class KPPPDevice;
|
||||
class KPPPProtocol;
|
||||
class KPPPOptionHandler;
|
||||
@@ -48,6 +54,8 @@ class KPPPInterface : public KPPPLayer {
|
||||
KPPPInterface(const KPPPInterface& copy);
|
||||
KPPPInterface& operator= (const KPPPInterface& copy);
|
||||
|
||||
public:
|
||||
// we should set to private after finishing test
|
||||
// only PPPManager may construct us!
|
||||
KPPPInterface(const char *name, ppp_interface_entry *entry,
|
||||
ppp_interface_id ID, const driver_settings *settings,
|
||||
@@ -75,7 +83,7 @@ class KPPPInterface : public KPPPLayer {
|
||||
{ return fLCP; }
|
||||
|
||||
//! Returns the interfac's ifnet structure that is exported to the netstack.
|
||||
struct ifnet *Ifnet() const
|
||||
net_device *Ifnet() const
|
||||
{ return fIfnet; }
|
||||
|
||||
const char *Username() const;
|
||||
@@ -220,11 +228,11 @@ class KPPPInterface : public KPPPLayer {
|
||||
virtual bool IsAllowedToSend() const;
|
||||
// always returns true
|
||||
|
||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber);
|
||||
// sends the packet to the next handler (normally the device)
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||
|
||||
status_t ReceiveFromDevice(struct mbuf *packet);
|
||||
status_t ReceiveFromDevice(net_buffer *packet);
|
||||
// This must not block KPPPDevice::Send()!
|
||||
|
||||
void Pulse();
|
||||
@@ -255,7 +263,7 @@ class KPPPInterface : public KPPPLayer {
|
||||
ppp_interface_id fID;
|
||||
// the manager assigns an ID to every interface
|
||||
driver_settings *fSettings;
|
||||
struct ifnet *fIfnet;
|
||||
net_device *fIfnet;
|
||||
|
||||
char *fUsername, *fPassword;
|
||||
|
||||
@@ -288,7 +296,7 @@ class KPPPInterface : public KPPPLayer {
|
||||
KPPPStateMachine fStateMachine;
|
||||
KPPPLCP fLCP;
|
||||
KPPPReportManager fReportManager;
|
||||
BLocker& fLock;
|
||||
mutex& fLock;
|
||||
int32 fDeleteCounter;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include <KPPPStateMachine.h>
|
||||
#endif
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <NetBufferUtilities.h>
|
||||
|
||||
class KPPPLCPExtension;
|
||||
class KPPPOptionHandler;
|
||||
|
||||
@@ -79,15 +82,12 @@ class KPPPLCP : public KPPPProtocol {
|
||||
KPPPProtocol *Target() const
|
||||
{ return fTarget; }
|
||||
|
||||
uint32 AdditionalOverhead() const;
|
||||
// the overhead caused by the target, the device, and the interface
|
||||
|
||||
virtual bool Up();
|
||||
virtual bool Down();
|
||||
|
||||
virtual status_t Send(struct mbuf *packet,
|
||||
virtual status_t Send(net_buffer *packet,
|
||||
uint16 protocolNumber = PPP_LCP_PROTOCOL);
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber);
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber);
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ class KPPPLCPExtension {
|
||||
// called by netstack (forwarded by KPPPInterface)
|
||||
|
||||
//! Must be overridden. Called when an LCP packet with your code is received.
|
||||
virtual status_t Receive(struct mbuf *packet, uint8 code) = 0;
|
||||
virtual status_t Receive(net_buffer *packet, uint8 code) = 0;
|
||||
|
||||
virtual void Reset();
|
||||
virtual void Pulse();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <KPPPDefs.h>
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
class KPPPLayer {
|
||||
protected:
|
||||
@@ -48,11 +49,11 @@ class KPPPLayer {
|
||||
virtual bool IsAllowedToSend() const = 0;
|
||||
|
||||
//! Send a packet with the given protocol number.
|
||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||
//! Receive a packet with the given protocol number.
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0;
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||
|
||||
status_t SendToNext(struct mbuf *packet, uint16 protocolNumber) const;
|
||||
status_t SendToNext(net_buffer *packet, uint16 protocolNumber) const;
|
||||
// send the packet to the next layer
|
||||
|
||||
virtual void Pulse();
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#ifndef _K_PPP_MANAGER__H
|
||||
#define _K_PPP_MANAGER__H
|
||||
|
||||
#include "net_module.h"
|
||||
#include <module.h>
|
||||
#include <net_device.h>
|
||||
#include <PPPControl.h>
|
||||
#include <PPPReportDefs.h>
|
||||
|
||||
|
||||
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "interfaces/ppp"
|
||||
#define PPP_INTERFACE_MODULE_NAME NETWORK_MODULES_ROOT "/ppp/KPPPManager/v1"
|
||||
|
||||
#define PPP_UNDEFINED_INTERFACE_ID 0
|
||||
// CreateInterface() returns this value on failure
|
||||
@@ -34,8 +34,7 @@ typedef struct ppp_interface_entry {
|
||||
deletes them when they are not needed anymore.
|
||||
*/
|
||||
typedef struct ppp_interface_module_info {
|
||||
kernel_net_module_info knminfo;
|
||||
//!< Exports needed network module functions.
|
||||
struct module_info info;
|
||||
|
||||
ppp_interface_id (*CreateInterface)(const driver_settings *settings,
|
||||
ppp_interface_id parentID);
|
||||
@@ -46,7 +45,9 @@ typedef struct ppp_interface_module_info {
|
||||
bool (*RemoveInterface)(ppp_interface_id ID);
|
||||
// remove the interface from database (make sure you can delete it yourself!)
|
||||
|
||||
ifnet *(*RegisterInterface)(ppp_interface_id ID);
|
||||
net_device *(*RegisterInterface)(ppp_interface_id ID);
|
||||
KPPPInterface *(*GetInterface)(ppp_interface_id ID);
|
||||
// for accessing KPPPInterface directly
|
||||
bool (*UnregisterInterface)(ppp_interface_id ID);
|
||||
|
||||
status_t (*ControlInterface)(ppp_interface_id ID, uint32 op, void *data,
|
||||
|
||||
@@ -105,9 +105,9 @@ class KPPPProtocol : public KPPPLayer {
|
||||
virtual bool IsAllowedToSend() const;
|
||||
|
||||
//! Encapsulate the packet with the given protocol number.
|
||||
virtual status_t Send(struct mbuf *packet, uint16 protocolNumber) = 0;
|
||||
virtual status_t Send(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||
//! Receive a packet with the given protocol number.
|
||||
virtual status_t Receive(struct mbuf *packet, uint16 protocolNumber) = 0;
|
||||
virtual status_t Receive(net_buffer *packet, uint16 protocolNumber) = 0;
|
||||
|
||||
protected:
|
||||
//! \brief Requests Up() to be called.
|
||||
|
||||
@@ -13,10 +13,13 @@
|
||||
|
||||
#include <TemplateList.h>
|
||||
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
|
||||
class KPPPReportManager {
|
||||
public:
|
||||
KPPPReportManager(BLocker& lock);
|
||||
KPPPReportManager(mutex& lock);
|
||||
~KPPPReportManager();
|
||||
|
||||
static bool SendReport(thread_id thread, const ppp_report_packet *report);
|
||||
@@ -30,7 +33,7 @@ class KPPPReportManager {
|
||||
// returns false if reply was bad (or an error occured)
|
||||
|
||||
private:
|
||||
BLocker& fLock;
|
||||
mutex& fLock;
|
||||
TemplateList<ppp_report_request*> fReportRequests;
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ class KPPPProtocol;
|
||||
#include <KPPPInterface.h>
|
||||
#endif
|
||||
|
||||
#include <Locker.h>
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
class PPPManager;
|
||||
class KPPPInterface;
|
||||
@@ -116,22 +117,22 @@ class KPPPStateMachine {
|
||||
void CloseEvent();
|
||||
void TOGoodEvent();
|
||||
void TOBadEvent();
|
||||
void RCRGoodEvent(struct mbuf *packet);
|
||||
void RCRBadEvent(struct mbuf *nak, struct mbuf *reject);
|
||||
void RCAEvent(struct mbuf *packet);
|
||||
void RCNEvent(struct mbuf *packet);
|
||||
void RTREvent(struct mbuf *packet);
|
||||
void RTAEvent(struct mbuf *packet);
|
||||
void RUCEvent(struct mbuf *packet, uint16 protocolNumber,
|
||||
void RCRGoodEvent(net_buffer *packet);
|
||||
void RCRBadEvent(net_buffer *nak, net_buffer *reject);
|
||||
void RCAEvent(net_buffer *packet);
|
||||
void RCNEvent(net_buffer *packet);
|
||||
void RTREvent(net_buffer *packet);
|
||||
void RTAEvent(net_buffer *packet);
|
||||
void RUCEvent(net_buffer *packet, uint16 protocolNumber,
|
||||
uint8 code = PPP_PROTOCOL_REJECT);
|
||||
void RXJGoodEvent(struct mbuf *packet);
|
||||
void RXJBadEvent(struct mbuf *packet);
|
||||
void RXREvent(struct mbuf *packet);
|
||||
void RXJGoodEvent(net_buffer *packet);
|
||||
void RXJBadEvent(net_buffer *packet);
|
||||
void RXREvent(net_buffer *packet);
|
||||
|
||||
// general events (for Good/Bad events)
|
||||
void TimerEvent();
|
||||
void RCREvent(struct mbuf *packet);
|
||||
void RXJEvent(struct mbuf *packet);
|
||||
void RCREvent(net_buffer *packet);
|
||||
void RXJEvent(net_buffer *packet);
|
||||
|
||||
// actions
|
||||
void IllegalEvent(ppp_event event);
|
||||
@@ -142,12 +143,12 @@ class KPPPStateMachine {
|
||||
void InitializeRestartCount();
|
||||
void ZeroRestartCount();
|
||||
bool SendConfigureRequest();
|
||||
bool SendConfigureAck(struct mbuf *packet);
|
||||
bool SendConfigureNak(struct mbuf *packet);
|
||||
bool SendConfigureAck(net_buffer *packet);
|
||||
bool SendConfigureNak(net_buffer *packet);
|
||||
bool SendTerminateRequest();
|
||||
bool SendTerminateAck(struct mbuf *request = NULL);
|
||||
bool SendCodeReject(struct mbuf *packet, uint16 protocolNumber, uint8 code);
|
||||
bool SendEchoReply(struct mbuf *request);
|
||||
bool SendTerminateAck(net_buffer *request = NULL);
|
||||
bool SendCodeReject(net_buffer *packet, uint16 protocolNumber, uint8 code);
|
||||
bool SendEchoReply(net_buffer *request);
|
||||
|
||||
void BringProtocolsUp();
|
||||
uint32 BringPhaseUp();
|
||||
@@ -162,7 +163,7 @@ class KPPPStateMachine {
|
||||
ppp_state fState;
|
||||
ppp_phase fPhase;
|
||||
|
||||
vint32 fID;
|
||||
int32 fID;
|
||||
uint32 fMagicNumber;
|
||||
int32 fLastConnectionReportCode;
|
||||
|
||||
@@ -177,7 +178,7 @@ class KPPPStateMachine {
|
||||
// the ID we used for the last configure/terminate/echo request
|
||||
bigtime_t fNextTimeout;
|
||||
|
||||
BLocker fLock;
|
||||
mutex fLock;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,76 @@
|
||||
#include <PPPDefs.h>
|
||||
|
||||
|
||||
#define IF_NAMESIZE 32
|
||||
// copied from if.h
|
||||
|
||||
struct control_net_module_args {
|
||||
char ifr_name[IF_NAMESIZE];
|
||||
const char* name;
|
||||
uint32 op;
|
||||
void* data;
|
||||
size_t length;
|
||||
// union {
|
||||
// struct sockaddr ifr_addr;
|
||||
// struct sockaddr ifr_dstaddr;
|
||||
// struct sockaddr ifr_broadaddr;
|
||||
// struct sockaddr ifr_mask;
|
||||
// struct ifreq_stats ifr_stats;
|
||||
// struct route_entry ifr_route;
|
||||
// int ifr_flags;
|
||||
// int ifr_index;
|
||||
// int ifr_metric;
|
||||
// int ifr_mtu;
|
||||
// int ifr_media;
|
||||
// int ifr_type;
|
||||
// int ifr_reqcap;
|
||||
// int ifr_count;
|
||||
// uint8_t* ifr_data;
|
||||
// };
|
||||
};
|
||||
// copied from libppp
|
||||
|
||||
|
||||
enum {
|
||||
// Paranoia mode: be far away of B_DEVICE_OP_CODES_END opcodes!!!
|
||||
// You never know what another device driver ioctl() will do
|
||||
// if think our NET_STACK_* is in fact his DO_RISKY_BUSINESS opcode, or whatever...
|
||||
NET_IOCTL_BASE = 0xbe230000,
|
||||
NET_STACK_IOCTL_BASE = NET_IOCTL_BASE + 0x200
|
||||
};
|
||||
|
||||
enum {
|
||||
NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args *
|
||||
NET_STACK_BIND, // sockaddr_args *
|
||||
NET_STACK_RECVFROM, // struct msghdr *
|
||||
NET_STACK_RECV, // transfer_args *
|
||||
NET_STACK_SENDTO, // struct msghdr *
|
||||
NET_STACK_SEND, // transfer_args *
|
||||
NET_STACK_LISTEN, // int_args * (value = backlog)
|
||||
NET_STACK_ACCEPT, // sockaddr_args *
|
||||
NET_STACK_CONNECT, // sockaddr_args *
|
||||
NET_STACK_SHUTDOWN, // int_args * (value = how)
|
||||
NET_STACK_GETSOCKOPT, // sockopt_args *
|
||||
NET_STACK_SETSOCKOPT, // sockopt_args *
|
||||
NET_STACK_GETSOCKNAME, // sockaddr_args *
|
||||
NET_STACK_GETPEERNAME, // sockaddr_args *
|
||||
|
||||
NET_STACK_SYSCTL, // sysctl_args *
|
||||
NET_STACK_SELECT, // select_args *
|
||||
NET_STACK_DESELECT, // select_args *
|
||||
|
||||
NET_STACK_GET_COOKIE, // void **
|
||||
|
||||
NET_STACK_STOP,
|
||||
|
||||
NET_STACK_NOTIFY_SOCKET_EVENT, // notify_socket_event_args * (userland stack only)
|
||||
|
||||
NET_STACK_CONTROL_NET_MODULE,
|
||||
|
||||
NET_STACK_IOCTL_MAX
|
||||
};
|
||||
|
||||
|
||||
// various constants
|
||||
#define PPP_HANDLER_NAME_LENGTH_LIMIT 63
|
||||
// if the name is longer than this value it will be truncated to fit the structure
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
#include <directories.h>
|
||||
|
||||
#include "net_module.h"
|
||||
|
||||
|
||||
typedef uint32 ppp_interface_id;
|
||||
|
||||
@@ -37,7 +35,8 @@ typedef uint32 ppp_interface_id;
|
||||
#define PPP_SERVER_MODE_VALUE "Server"
|
||||
|
||||
// path defines
|
||||
#define PPP_MODULES_PATH NETWORK_MODULES_ROOT "ppp"
|
||||
#define NETWORK_MODULES_ROOT "network"
|
||||
#define PPP_MODULES_PATH NETWORK_MODULES_ROOT "/ppp"
|
||||
#define PTP_INTERFACE_SETTINGS_PATH \
|
||||
kUserSettingsDirectory "/kernel/drivers/ptpnet"
|
||||
// TODO: should be: /etc/ptpnet
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef __PPP_DEV_H
|
||||
#define __PPP_DEV_H
|
||||
#include <net_device.h>
|
||||
#include <net_stack.h>
|
||||
|
||||
#include <KPPPInterface.h>
|
||||
|
||||
#include <lock.h>
|
||||
#include <util/AutoLock.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
|
||||
struct ppp_device : net_device, DoublyLinkedListLinkImpl<ppp_device> {
|
||||
KPPPInterface * KPPP_Interface;
|
||||
uint32 frame_size;
|
||||
net_fifo ppp_fifo;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -10,6 +10,7 @@ if $(TARGET_PLATFORM) != haiku {
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||
headers ] : true ;
|
||||
@@ -19,18 +20,18 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
|
||||
StaticLibrary libppp.a :
|
||||
strlcat.c
|
||||
driver_settings.c
|
||||
driver_settings.cpp
|
||||
settings_tools.cpp
|
||||
KPPPUtils.cpp
|
||||
|
||||
_libppputils.cpp
|
||||
PPPInterface.cpp
|
||||
PPPInterfaceListener.cpp
|
||||
PPPManager.cpp
|
||||
MessageDriverSettingsUtils.cpp
|
||||
: libnetwork.so libbnetapi.so
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles strlcat.c ] = [ FDirName $(HAIKU_TOP) src system libroot posix string ] ;
|
||||
SEARCH on [ FGristFiles driver_settings.c ] = [ FDirName $(HAIKU_TOP) src system libroot os ] ;
|
||||
SEARCH on [ FGristFiles driver_settings.cpp ] = [ FDirName $(HAIKU_TOP) src system libroot os ] ;
|
||||
SEARCH on [ FGristFiles settings_tools.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
|
||||
SEARCH on [ FGristFiles KPPPUtils.cpp ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
|
||||
|
||||
@@ -13,13 +13,20 @@
|
||||
#include "PPPInterface.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <unistd.h>
|
||||
#include "_libppputils.h"
|
||||
|
||||
#include <Path.h>
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <NetworkDevice.h>
|
||||
#include <NetworkInterface.h>
|
||||
|
||||
|
||||
/*! \brief Sets the interface to \a ID.
|
||||
|
||||
@@ -27,7 +34,9 @@
|
||||
*/
|
||||
PPPInterface::PPPInterface(ppp_interface_id ID)
|
||||
{
|
||||
fFD = open(get_stack_driver_path(), O_RDWR);
|
||||
// printf("direct constructor\n");
|
||||
int family = AF_INET;
|
||||
fFD = socket(family, SOCK_DGRAM, 0);
|
||||
|
||||
SetTo(ID);
|
||||
}
|
||||
@@ -36,7 +45,10 @@ PPPInterface::PPPInterface(ppp_interface_id ID)
|
||||
//! Copy constructor.
|
||||
PPPInterface::PPPInterface(const PPPInterface& copy)
|
||||
{
|
||||
fFD = open(get_stack_driver_path(), O_RDWR);
|
||||
// printf("Copy constructor\n");
|
||||
// fFD = open(get_stack_driver_path(), O_RDWR);
|
||||
int family = AF_INET;
|
||||
fFD = socket(family, SOCK_DGRAM, 0);
|
||||
|
||||
SetTo(copy.ID());
|
||||
}
|
||||
@@ -45,6 +57,7 @@ PPPInterface::PPPInterface(const PPPInterface& copy)
|
||||
//! Destructor.
|
||||
PPPInterface::~PPPInterface()
|
||||
{
|
||||
// printf("Destructor\n");
|
||||
if (fFD >= 0)
|
||||
close(fFD);
|
||||
}
|
||||
@@ -64,6 +77,7 @@ PPPInterface::InitCheck() const
|
||||
{
|
||||
if (fFD < 0)
|
||||
return B_ERROR;
|
||||
|
||||
if (fID == PPP_UNDEFINED_INTERFACE_ID)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
@@ -87,19 +101,29 @@ PPPInterface::InitCheck() const
|
||||
status_t
|
||||
PPPInterface::SetTo(ppp_interface_id ID)
|
||||
{
|
||||
if (fFD < 0)
|
||||
// printf("Set To %ld begin=============================\n", ID);
|
||||
if (fFD < 0) {
|
||||
printf("No fFD\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
fID = ID;
|
||||
|
||||
ppp_interface_info_t info;
|
||||
// printf("SetTo info:%p\n", &info);
|
||||
if (GetInterfaceInfo(&info)) {
|
||||
fName = info.info.name;
|
||||
fID = ID;
|
||||
// printf("%s fine: name:%s, fID:%ld\n", __func__, info.info.name, fID);
|
||||
} else {
|
||||
fName = "";
|
||||
fID = PPP_UNDEFINED_INTERFACE_ID;
|
||||
// printf("%s fail: name:%s, fID:%ld\n", __func__, "", fID);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// printf("Set To %ld end =============================\n", ID);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -119,23 +143,32 @@ PPPInterface::SetTo(ppp_interface_id ID)
|
||||
status_t
|
||||
PPPInterface::Control(uint32 op, void *data, size_t length) const
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
if (InitCheck() != B_OK) {
|
||||
printf("%s:InitCheck fail\n", __func__);
|
||||
return InitCheck();
|
||||
}
|
||||
|
||||
ppp_control_info control;
|
||||
ppp_control_info info;
|
||||
control_net_module_args args;
|
||||
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||
args.op = PPPC_CONTROL_INTERFACE;
|
||||
args.data = &control;
|
||||
args.length = sizeof(control);
|
||||
args.data = &info;
|
||||
args.length = sizeof(ppp_control_info);
|
||||
|
||||
control.index = ID();
|
||||
control.op = op;
|
||||
control.data = data;
|
||||
control.length = length;
|
||||
info.index = ID();
|
||||
info.op = op;
|
||||
info.data = data;
|
||||
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
|
||||
PPPInterface::SetUsername(const char *username) const
|
||||
{
|
||||
printf("PPPInterface::SetUsername\n");
|
||||
if (InitCheck() != B_OK || !username)
|
||||
return false;
|
||||
|
||||
@@ -155,6 +189,7 @@ PPPInterface::SetUsername(const char *username) const
|
||||
bool
|
||||
PPPInterface::SetPassword(const char *password) const
|
||||
{
|
||||
printf("PPPInterface::SetPassword\n");
|
||||
if (InitCheck() != B_OK || !password)
|
||||
return false;
|
||||
|
||||
@@ -167,6 +202,7 @@ PPPInterface::SetPassword(const char *password) const
|
||||
bool
|
||||
PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
|
||||
{
|
||||
printf("PPPInterface::SetAskBeforeConnecting\n");
|
||||
if (InitCheck() != B_OK)
|
||||
return false;
|
||||
|
||||
@@ -188,6 +224,7 @@ PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
|
||||
status_t
|
||||
PPPInterface::GetSettingsEntry(BEntry *entry) const
|
||||
{
|
||||
printf("PPPInterface::GetSettingsEntry\n");
|
||||
if (InitCheck() != B_OK)
|
||||
return InitCheck();
|
||||
else if (!entry || strlen(Name()) == 0)
|
||||
@@ -205,10 +242,103 @@ PPPInterface::GetSettingsEntry(BEntry *entry) const
|
||||
bool
|
||||
PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
|
||||
{
|
||||
// printf("%s info at:%p", __func__, info);
|
||||
if (InitCheck() != B_OK || !info) {
|
||||
// printf("InitCheck fail %s info at:%p", __func__, info);
|
||||
return false;
|
||||
}
|
||||
|
||||
return Control(PPPC_GET_INTERFACE_INFO, info, sizeof(ppp_interface_info_t))
|
||||
== B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::ControlDevice(ppp_device_info_t *info) const
|
||||
{
|
||||
// printf("%s info at:%p", __func__, info);
|
||||
if (InitCheck() != B_OK || !info)
|
||||
return false;
|
||||
|
||||
return Control(PPPC_GET_INTERFACE_INFO, &info, sizeof(ppp_interface_info_t))
|
||||
ppp_control_info controlInfo;
|
||||
controlInfo.op = PPPC_GET_DEVICE_INFO;
|
||||
controlInfo.index = 0;
|
||||
controlInfo.data = info;
|
||||
controlInfo.length = sizeof(ppp_device_info_t);
|
||||
|
||||
return Control(PPPC_CONTROL_DEVICE, &controlInfo, sizeof(ppp_control_info))
|
||||
== B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::ControlOptionHandler(ppp_simple_handler_info_t *info, uint32 handlerindex, uint32 handlerOP) const
|
||||
{
|
||||
// printf("%s info at:%p", __func__, info);
|
||||
if (InitCheck() != B_OK || !info)
|
||||
return false;
|
||||
|
||||
ppp_control_info controlInfo;
|
||||
controlInfo.index = handlerindex;
|
||||
controlInfo.op = handlerOP;
|
||||
controlInfo.data = info;
|
||||
controlInfo.length = sizeof(ppp_simple_handler_info_t);
|
||||
|
||||
return Control(PPPC_CONTROL_OPTION_HANDLER, &controlInfo, sizeof(ppp_control_info))
|
||||
== B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::ControlChild(void *info, uint32 childindex, uint32 childOP) const
|
||||
{
|
||||
// printf("%s info at:%p", __func__, info);
|
||||
if (InitCheck() != B_OK || !info)
|
||||
return false;
|
||||
|
||||
ppp_control_info controlInfo;
|
||||
controlInfo.index = childindex;
|
||||
controlInfo.op = childOP;
|
||||
controlInfo.data = info;
|
||||
// controlInfo.length = sizeof(ppp_simple_handler_info_t);
|
||||
|
||||
return Control(PPPC_CONTROL_CHILD, &controlInfo, sizeof(ppp_control_info))
|
||||
== B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::ControlLCPExtension(ppp_simple_handler_info_t *info, uint32 LCPExtensionindex, uint32 LCPExtensionOP) const
|
||||
{
|
||||
// printf("%s info at:%p", __func__, info);
|
||||
if (InitCheck() != B_OK || !info)
|
||||
return false;
|
||||
|
||||
ppp_control_info controlInfo;
|
||||
controlInfo.index = LCPExtensionindex;
|
||||
controlInfo.op = LCPExtensionOP;
|
||||
controlInfo.data = info;
|
||||
controlInfo.length = sizeof(ppp_simple_handler_info_t);
|
||||
|
||||
return Control(PPPC_CONTROL_LCP_EXTENSION, &controlInfo, sizeof(ppp_control_info))
|
||||
== B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PPPInterface::ControlProtocol(ppp_protocol_info_t *info, uint32 protocolindex, uint32 protocolOP) const
|
||||
{
|
||||
// printf("%s info at:%p", __func__, info);
|
||||
if (InitCheck() != B_OK || !info)
|
||||
return false;
|
||||
|
||||
ppp_control_info controlInfo;
|
||||
controlInfo.index = protocolindex;
|
||||
controlInfo.op = protocolOP;
|
||||
controlInfo.data = info;
|
||||
controlInfo.length = sizeof(ppp_protocol_info_t);
|
||||
|
||||
return Control(PPPC_CONTROL_PROTOCOL, &controlInfo, sizeof(ppp_control_info))
|
||||
== B_OK;
|
||||
}
|
||||
|
||||
@@ -222,6 +352,7 @@ PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
|
||||
bool
|
||||
PPPInterface::GetStatistics(ppp_statistics *statistics) const
|
||||
{
|
||||
printf("PPPInterface::GetStatistics\n");
|
||||
if (!statistics)
|
||||
return false;
|
||||
|
||||
@@ -233,6 +364,7 @@ PPPInterface::GetStatistics(ppp_statistics *statistics) const
|
||||
bool
|
||||
PPPInterface::HasSettings(const driver_settings *settings) const
|
||||
{
|
||||
printf("PPPInterface::HasSettings\n");
|
||||
if (InitCheck() != B_OK || !settings)
|
||||
return false;
|
||||
|
||||
@@ -251,8 +383,23 @@ PPPInterface::Up() const
|
||||
if (InitCheck() != B_OK)
|
||||
return false;
|
||||
|
||||
BNetworkInterface interface(Name());
|
||||
if (!interface.Exists())
|
||||
return false;
|
||||
|
||||
int32 currentFlags = interface.Flags();
|
||||
currentFlags |= IFF_UP;
|
||||
|
||||
status_t status = interface.SetFlags(currentFlags);
|
||||
|
||||
if (status != B_OK)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
int32 id = ID();
|
||||
control_net_module_args args;
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||
args.op = PPPC_BRING_INTERFACE_UP;
|
||||
args.data = &id;
|
||||
@@ -269,8 +416,23 @@ PPPInterface::Down() const
|
||||
if (InitCheck() != B_OK)
|
||||
return false;
|
||||
|
||||
BNetworkInterface interface(Name());
|
||||
if (!interface.Exists())
|
||||
return false;
|
||||
|
||||
int32 currentFlags = interface.Flags();
|
||||
currentFlags &= ~IFF_UP;
|
||||
|
||||
status_t status = interface.SetFlags(currentFlags);
|
||||
|
||||
if (status != B_OK)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
int32 id = ID();
|
||||
control_net_module_args args;
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||
args.op = PPPC_BRING_INTERFACE_DOWN;
|
||||
args.data = &id;
|
||||
@@ -292,6 +454,7 @@ bool
|
||||
PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
|
||||
int32 flags) const
|
||||
{
|
||||
printf("PPPInterface::EnableReports\n");
|
||||
ppp_report_request request;
|
||||
request.type = type;
|
||||
request.thread = thread;
|
||||
@@ -311,6 +474,7 @@ PPPInterface::EnableReports(ppp_report_type type, thread_id thread,
|
||||
bool
|
||||
PPPInterface::DisableReports(ppp_report_type type, thread_id thread) const
|
||||
{
|
||||
printf("PPPInterface::DisableReports\n");
|
||||
ppp_report_request request;
|
||||
request.type = type;
|
||||
request.thread = thread;
|
||||
|
||||
@@ -20,16 +20,49 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <settings_tools.h>
|
||||
#include <unistd.h>
|
||||
#include "_libppputils.h"
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <Message.h>
|
||||
#include <Messenger.h>
|
||||
#include <NetworkDevice.h>
|
||||
#include <NetworkInterface.h>
|
||||
#include <NetworkRoster.h>
|
||||
|
||||
#include <NetServer.h>
|
||||
|
||||
//! Constructor. Does nothing special.
|
||||
PPPManager::PPPManager()
|
||||
{
|
||||
fFD = open(get_stack_driver_path(), O_RDWR);
|
||||
// fFD = open(get_stack_driver_path(), O_RDWR);
|
||||
int family = AF_INET;
|
||||
|
||||
fFD = socket(family, SOCK_DGRAM, 0);
|
||||
|
||||
// FileDescriptorCloser closer(socket);
|
||||
|
||||
// ifaliasreq request;
|
||||
// strlcpy(request.ifra_name, name, IF_NAMESIZE);
|
||||
// request.ifra_index = address.Index();
|
||||
// request.ifra_flags = address.Flags();
|
||||
|
||||
// memcpy(&request.ifra_addr, &address.Address().SockAddr(),
|
||||
// address.Address().Length());
|
||||
// memcpy(&request.ifra_mask, &address.Mask().SockAddr(),
|
||||
// address.Mask().Length());
|
||||
// memcpy(&request.ifra_broadaddr, &address.Broadcast().SockAddr(),
|
||||
// address.Broadcast().Length());
|
||||
|
||||
// if (ioctl(socket, option, &request, sizeof(struct ifaliasreq)) < 0)
|
||||
// return errno;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +166,7 @@ PPPManager::Control(uint32 op, void *data, size_t length) const
|
||||
return B_ERROR;
|
||||
|
||||
control_net_module_args args;
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = PPP_INTERFACE_MODULE_NAME;
|
||||
args.op = op;
|
||||
args.data = data;
|
||||
@@ -169,6 +203,7 @@ PPPManager::ControlModule(const char *name, uint32 op, void *data,
|
||||
return B_ERROR;
|
||||
|
||||
control_net_module_args args;
|
||||
sprintf(args.ifr_name, "%s", "ppp1");
|
||||
args.name = name;
|
||||
args.op = op;
|
||||
args.data = data;
|
||||
@@ -207,13 +242,72 @@ PPPManager::CreateInterface(const driver_settings *settings) const
|
||||
ppp_interface_id
|
||||
PPPManager::CreateInterfaceWithName(const char *name) const
|
||||
{
|
||||
ppp_interface_description_info info;
|
||||
info.u.name = name;
|
||||
ppp_interface_id ID = InterfaceWithName(name);
|
||||
|
||||
if (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;
|
||||
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
|
||||
while (true) {
|
||||
requestCount = *count = CountInterfaces(filter);
|
||||
if (*count == -1)
|
||||
if (*count <= 0) {
|
||||
printf("No interface, count, first round:%ld\n", *count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
requestCount += 10;
|
||||
// request some more interfaces in case some are added in the mean time
|
||||
interfaces = new ppp_interface_id[requestCount];
|
||||
// printf("interfaces addr: %p\n, requestCount: %ld", interfaces, requestCount);
|
||||
*count = GetInterfaces(interfaces, requestCount, filter);
|
||||
if (*count == -1) {
|
||||
if (*count <= 0) {
|
||||
printf("No interface, count second round:%ld\n", *count);
|
||||
delete interfaces;
|
||||
return NULL;
|
||||
}
|
||||
@@ -345,12 +443,17 @@ PPPManager::InterfaceWithName(const char *name) const
|
||||
int32 count;
|
||||
ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
|
||||
|
||||
if (!interfaces)
|
||||
if (!interfaces || count <= 0) {
|
||||
printf("ERROR: Could not get ppp name:%s\n", name);
|
||||
return PPP_UNDEFINED_INTERFACE_ID;
|
||||
}
|
||||
|
||||
// printf("first ID:%ld count:%ld\n", interfaces[0], count);
|
||||
|
||||
ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
|
||||
PPPInterface interface;
|
||||
ppp_interface_info_t info;
|
||||
// printf("internal info is at: %p\n", &info);
|
||||
|
||||
for (int32 index = 0; index < count; index++) {
|
||||
interface.SetTo(interfaces[index]);
|
||||
@@ -374,11 +477,79 @@ PPPManager::InterfaceWithName(const char *name) const
|
||||
}
|
||||
|
||||
|
||||
//! Returns the number of existing interfaces or a negative value on error.
|
||||
bool
|
||||
is_ppp_interface(const char* name)
|
||||
{
|
||||
// size_t length = strlen(name);
|
||||
// if (length < 8)
|
||||
// putchar('\t');
|
||||
// else
|
||||
// printf("\n\t");
|
||||
|
||||
// get link level interface for this interface
|
||||
|
||||
BNetworkInterface interface(name);
|
||||
BNetworkAddress linkAddress;
|
||||
status_t status = interface.GetHardwareAddress(linkAddress);
|
||||
if (status == B_OK) {
|
||||
// const char *type = "unknown";
|
||||
switch (linkAddress.LinkLevelType()) {
|
||||
case IFT_ETHER:
|
||||
// type = "Ethernet";
|
||||
// printf("%s\n", type);
|
||||
break;
|
||||
case IFT_LOOP:
|
||||
// type = "Local Loopback";
|
||||
// printf("%s\n", type);
|
||||
break;
|
||||
case IFT_MODEM:
|
||||
// type = "Modem";
|
||||
// printf("%s\n", type);
|
||||
break;
|
||||
case IFT_PPP:
|
||||
// type = "PPP";
|
||||
// printf("%s\n", type);
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
// printf("%s\n", type);
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//! Returns the number of ppp interfaces
|
||||
int32
|
||||
count_ppp_interface(void)
|
||||
{
|
||||
int32 count = 0;
|
||||
|
||||
// get a list of all ppp interfaces
|
||||
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||
|
||||
BNetworkInterface interface;
|
||||
uint32 cookie = 0;
|
||||
|
||||
while (roster.GetNextInterface(&cookie, interface) == B_OK) {
|
||||
if (is_ppp_interface(interface.Name()))
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
//! Returns the number of existing interfaces or a negative value on error.
|
||||
int32
|
||||
PPPManager::CountInterfaces(ppp_interface_filter filter) const
|
||||
{
|
||||
return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter));
|
||||
// return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter));
|
||||
return count_ppp_interface();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
#include "_libppputils.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
char*
|
||||
get_stack_driver_path()
|
||||
{
|
||||
char *path;
|
||||
|
||||
// user-defined stack driver path?
|
||||
path = getenv("NET_STACK_DRIVER_PATH");
|
||||
if (path)
|
||||
return path;
|
||||
|
||||
// use the default stack driver path
|
||||
return NET_STACK_DRIVER_PATH;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef __libppputils__h
|
||||
#define __libppputils__h
|
||||
|
||||
#include <net_stack_driver.h>
|
||||
|
||||
|
||||
char *get_stack_driver_path();
|
||||
|
||||
|
||||
#endif
|
||||
@@ -40,6 +40,12 @@ class PPPInterface {
|
||||
bool GetStatistics(ppp_statistics *statistics) const;
|
||||
bool HasSettings(const driver_settings *settings) const;
|
||||
|
||||
bool ControlDevice(ppp_device_info_t *info) const;
|
||||
bool ControlProtocol(ppp_protocol_info_t *info, uint32 protocolindex, uint32 procotolOP) const;
|
||||
bool ControlOptionHandler(ppp_simple_handler_info_t *info, uint32 handlerindex, uint32 handlerOP) const;
|
||||
bool ControlLCPExtension(ppp_simple_handler_info_t *info, uint32 LCPExtensionindex, uint32 LCPExtensionOP) const;
|
||||
bool ControlChild(void *info, uint32 childindex, uint32 childOP) const;
|
||||
|
||||
bool Up() const;
|
||||
bool Down() const;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef _PPP_MANAGER__H
|
||||
#define _PPP_MANAGER__H
|
||||
|
||||
#include <Directory.h>
|
||||
#include <KPPPManager.h>
|
||||
#include <String.h>
|
||||
|
||||
@@ -33,6 +34,7 @@ class PPPManager {
|
||||
ppp_interface_id CreateInterface(const driver_settings *settings) const;
|
||||
ppp_interface_id CreateInterfaceWithName(const char *name) const;
|
||||
bool DeleteInterface(ppp_interface_id ID) const;
|
||||
bool DeleteInterface(const char* name) const;
|
||||
|
||||
ppp_interface_id *Interfaces(int32 *count,
|
||||
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const;
|
||||
|
||||
@@ -833,6 +833,9 @@ init_stack()
|
||||
// TODO: for now!
|
||||
register_domain_datalink_protocols(AF_INET, IFT_LOOP,
|
||||
"network/datalink_protocols/loopback_frame/v1", NULL);
|
||||
// add ppp datalink protocol
|
||||
register_domain_datalink_protocols(AF_INET, IFT_PPP,
|
||||
"network/datalink_protocols/ppp_frame/v1", NULL);
|
||||
register_domain_datalink_protocols(AF_INET6, IFT_LOOP,
|
||||
"network/datalink_protocols/loopback_frame/v1", NULL);
|
||||
register_domain_datalink_protocols(AF_INET, IFT_ETHER,
|
||||
|
||||
@@ -10,8 +10,8 @@ SubInclude HAIKU_TOP src bin network ftpd ;
|
||||
SubInclude HAIKU_TOP src bin network ifconfig ;
|
||||
SubInclude HAIKU_TOP src bin network mount_nfs ;
|
||||
SubInclude HAIKU_TOP src bin network netstat ;
|
||||
#SubInclude HAIKU_TOP src bin network pppconfig ;
|
||||
#SubInclude HAIKU_TOP src bin network ppp_up ;
|
||||
SubInclude HAIKU_TOP src bin network pppconfig ;
|
||||
SubInclude HAIKU_TOP src bin network ppp_up ;
|
||||
SubInclude HAIKU_TOP src bin network ping ;
|
||||
SubInclude HAIKU_TOP src bin network ping6 ;
|
||||
SubInclude HAIKU_TOP src bin network route ;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SubDir HAIKU_TOP src bin ppp_up ;
|
||||
SubDir HAIKU_TOP src bin network ppp_up ;
|
||||
|
||||
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
||||
|
||||
@@ -8,7 +8,10 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net app libroot shared interface libbe be root tracker textencoding
|
||||
root ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||
headers ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
@@ -24,7 +27,7 @@ BinCommand ppp_up :
|
||||
PPPStatusWindow.cpp
|
||||
PPPUpApplication.cpp
|
||||
:
|
||||
libppp.a be
|
||||
libppp.a be $(TARGET_LIBSUPC++) translation $(HAIKU_LOCALE_LIBS) root $(TARGET_NETWORK_LIBS)
|
||||
;
|
||||
|
||||
# Installation
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
#ifndef STATUS_VIEW__H
|
||||
#define STATUS_VIEW__H
|
||||
|
||||
#include <View.h>
|
||||
#include <Button.h>
|
||||
#include <PPPInterface.h>
|
||||
#include <StringView.h>
|
||||
|
||||
|
||||
class PPPStatusView : public BView {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SubDir HAIKU_TOP src bin pppconfig ;
|
||||
SubDir HAIKU_TOP src bin network pppconfig ;
|
||||
|
||||
SetSubDirSupportedPlatforms $(HAIKU_BONE_COMPATIBLE_PLATFORMS) ;
|
||||
|
||||
@@ -8,6 +8,7 @@ if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
||||
# Unfortunately we get more than we want, namely all POSIX headers.
|
||||
}
|
||||
|
||||
UsePrivateKernelHeaders ;
|
||||
UsePrivateHeaders net ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp
|
||||
headers ] : true ;
|
||||
@@ -17,7 +18,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
|
||||
BinCommand pppconfig :
|
||||
pppconfig.cpp
|
||||
:
|
||||
be libppp.a
|
||||
be libppp.a $(TARGET_LIBSUPC++) $(TARGET_NETWORK_LIBS)
|
||||
;
|
||||
|
||||
# Installation -- in the test directory for the time being
|
||||
|
||||
@@ -45,14 +45,16 @@ show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32 count;
|
||||
int32 count = 0;
|
||||
ppp_interface_id *interfaces = manager.Interfaces(&count, filter);
|
||||
|
||||
if(!interfaces) {
|
||||
if (!interfaces || count <= 0) {
|
||||
fprintf(stderr, "Error: Could not get interfaces information!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Get %ld ppp interfaces, first is %ld!\n", count, interfaces[0]);
|
||||
|
||||
ppp_interface_info_t info;
|
||||
PPPInterface interface;
|
||||
|
||||
@@ -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
|
||||
status_t
|
||||
disconnect(const char *name)
|
||||
@@ -220,7 +633,7 @@ delete_interface(const char *name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!manager.DeleteInterface(manager.InterfaceWithName(name))) {
|
||||
if (!manager.DeleteInterface(name)) {
|
||||
fprintf(stderr, "Error: Could not delete interface!\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -242,13 +655,20 @@ show_details(const char *name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
PPPInterface interface(manager.InterfaceWithName(name));
|
||||
if(interface.InitCheck() != B_OK) {
|
||||
ppp_interface_id ID = manager.InterfaceWithName(name);
|
||||
if (ID <= 0) {
|
||||
fprintf(stderr, "Error: Could not find interface: %s!\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PPPInterface interface(ID);
|
||||
if (interface.InitCheck() != B_OK) {
|
||||
fprintf(stderr, "Error: Could not find interface ID: %ld!\n", ID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ppp_interface_info_t info;
|
||||
// printf("ppp_interface_info_t addr:%p\n", &info);
|
||||
interface.GetInterfaceInfo(&info);
|
||||
|
||||
// type and name (if it has one)
|
||||
@@ -328,6 +748,33 @@ main(int argc, char *argv[])
|
||||
return delete_interface(argv[2]);
|
||||
else if (!strcmp(argv[1], "details"))
|
||||
return show_details(argv[2]);
|
||||
else if (!strcmp(argv[1], "getstatistics"))
|
||||
return getstatistics(argv[2]);
|
||||
else if (!strcmp(argv[1], "hassettings"))
|
||||
return hassettings(argv[2]);
|
||||
else if (!strcmp(argv[1], "enablereports"))
|
||||
return enablereports(argv[2]);
|
||||
else if (!strcmp(argv[1], "disablereports"))
|
||||
return disablereports(argv[2]);
|
||||
else if (!strcmp(argv[1], "controldevice"))
|
||||
return controldevice(argv[2]);
|
||||
else if (!strcmp(argv[1], "controlprotocol"))
|
||||
return controlprotocol(argv[2]);
|
||||
else if (!strcmp(argv[1], "controloptionhandler"))
|
||||
return controloptionhandler(argv[2]);
|
||||
else if (!strcmp(argv[1], "controllcpextension"))
|
||||
return controllcpextension(argv[2]);
|
||||
else if (!strcmp(argv[1], "controlchild"))
|
||||
return controlchild(argv[2]);
|
||||
else
|
||||
return print_help();
|
||||
} if (argc == 4) {
|
||||
if (!strcmp(argv[1], "setuser"))
|
||||
return setuser(argv[2], argv[3]);
|
||||
else if (!strcmp(argv[1], "setpass"))
|
||||
return setpass(argv[2], argv[3]);
|
||||
else if (!strcmp(argv[1], "setaskbeforeconnect"))
|
||||
return setaskbeforeconnect(argv[2], argv[3]);
|
||||
else
|
||||
return print_help();
|
||||
} else
|
||||
|
||||
Reference in New Issue
Block a user