* Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
* Distributed under the terms of the MIT License.
*/
\brief This class represents a PPP interface living in kernel space.
Use this class to control PPP interfaces and get the current interface settings.
You can also use it to enable/disable report messages.
*/
#include "PPPInterface.h"
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <unistd.h>
#include <Path.h>
#include <Directory.h>
#include <Entry.h>
#include <net/if.h>
#include <NetworkDevice.h>
#include <NetworkInterface.h>
\param ID The ID of the new interface.
*/
PPPInterface::PPPInterface(ppp_interface_id ID)
{
int family = AF_INET;
fFD = socket(family, SOCK_DGRAM, 0);
SetTo(ID);
}
PPPInterface::PPPInterface(const PPPInterface& copy)
{
int family = AF_INET;
fFD = socket(family, SOCK_DGRAM, 0);
SetTo(copy.ID());
}
PPPInterface::~PPPInterface()
{
if (fFD >= 0)
close(fFD);
}
You should always call this method after you constructed a PPPInterface object.
\return
- \c B_OK: Object could be initialized successfully and the interface exists.
- \c B_BAD_INDEX: The interface does not exist.
- \c B_ERROR: The PPP stack could not be loaded.
*/
status_t
PPPInterface::InitCheck() const
{
if (fFD < 0)
return B_ERROR;
if (fID == PPP_UNDEFINED_INTERFACE_ID)
return B_BAD_INDEX;
return B_OK;
}
If this fails it will set the interface's \a ID to \c PPP_UNDEFINED_INTERFACE_ID.
\param ID The ID of the new interface.
\return
- \c B_OK: Object could be initialized successfully and the interface exists.
- \c B_BAD_INDEX: The interface does not exist.
- any other value: The PPP stack could not be loaded.
\sa Control()
*/
status_t
PPPInterface::SetTo(ppp_interface_id ID)
{
if (fFD < 0) {
printf("No fFD\n");
return B_ERROR;
}
fID = ID;
ppp_interface_info_t info;
if (GetInterfaceInfo(&info)) {
fName = info.info.name;
fID = ID;
} else {
fName = "";
fID = PPP_UNDEFINED_INTERFACE_ID;
return B_ERROR;
}
return B_OK;
}
\param op Any value of ppp_control_ops.
\param data Some ops require you to pass a structure or other data using this
argument.
\param length Make sure this value is correct (e.g.: size of structure).
\return
- \c B_OK: Operation was successful.
- \c B_BAD_INDEX: The interface does not exist.
- any other value: The PPP stack could not be loaded.
*/
status_t
PPPInterface::Control(uint32 op, void *data, size_t length) const
{
if (InitCheck() != B_OK) {
printf("%s:InitCheck fail\n", __func__);
return InitCheck();
}
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 = &info;
args.length = sizeof(ppp_control_info);
info.index = ID();
info.op = op;
info.data = data;
info.length = length;
printf("PPPInterface::Control: ppp_control_info %p control_net_module_args %p data %p \n", &info, &args, data);
status_t status = ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args);
if (status != B_OK)
printf("%s:%s: fail\n", __FILE__, __func__);
return status;
}
bool
PPPInterface::SetUsername(const char *username) const
{
printf("PPPInterface::SetUsername\n");
if (InitCheck() != B_OK || !username)
return false;
return Control(PPPC_SET_USERNAME, const_cast<char*>(username), strlen(username))
== B_OK;
}
bool
PPPInterface::SetPassword(const char *password) const
{
printf("PPPInterface::SetPassword\n");
if (InitCheck() != B_OK || !password)
return false;
return Control(PPPC_SET_PASSWORD, const_cast<char*>(password), strlen(password))
== B_OK;
}
bool
PPPInterface::SetAskBeforeConnecting(bool askBeforeConnecting) const
{
printf("PPPInterface::SetAskBeforeConnecting\n");
if (InitCheck() != B_OK)
return false;
uint32 value = askBeforeConnecting ? 1 : 0;
return Control(PPPC_SET_ASK_BEFORE_CONNECTING, &value, sizeof(value)) == B_OK;
}
\param entry The entry gets stored in this argument.
\return
- \c B_OK: The settings file was saved in \a entry.
- \c B_BAD_INDEX: The interface does not exist.
- \c B_BAD_VALUE: Either \a entry was \c NULL or the interface is anonymous.
- any other value: The interface could not be found.
*/
status_t
PPPInterface::GetSettingsEntry(BEntry *entry) const
{
printf("PPPInterface::GetSettingsEntry\n");
if (InitCheck() != B_OK)
return InitCheck();
else if (!entry || strlen(Name()) == 0)
return B_BAD_VALUE;
BDirectory directory(PTP_INTERFACE_SETTINGS_PATH);
return directory.FindEntry(Name(), entry, true);
}
\return \c true on success, \c false otherwise.
*/
bool
PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
{
if (InitCheck() != B_OK || !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
{
if (InitCheck() != B_OK || !info)
return false;
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
{
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
{
if (InitCheck() != B_OK || !info)
return false;
ppp_control_info controlInfo;
controlInfo.index = childindex;
controlInfo.op = childOP;
controlInfo.data = info;
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
{
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
{
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;
}
\param statistics The structure is copied into this argument.
\return \c true on success, \c false otherwise.
*/
bool
PPPInterface::GetStatistics(ppp_statistics *statistics) const
{
printf("PPPInterface::GetStatistics\n");
if (!statistics)
return false;
return Control(PPPC_GET_STATISTICS, statistics, sizeof(ppp_statistics)) == B_OK;
}
bool
PPPInterface::HasSettings(const driver_settings *settings) const
{
printf("PPPInterface::HasSettings\n");
if (InitCheck() != B_OK || !settings)
return false;
if (Control(PPPC_HAS_INTERFACE_SETTINGS, const_cast<driver_settings*>(settings),
sizeof(driver_settings)) == B_OK)
return true;
return false;
}
bool
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;
args.length = sizeof(id);
return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args) == B_OK;
}
bool
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;
args.length = sizeof(id);
return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args) == B_OK;
}
\param type The type of report.
\param thread Receiver thread.
\param flags Optional flags.
\return \c true on success \c false otherwise.
*/
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;
request.flags = flags;
return Control(PPPC_ENABLE_REPORTS, &request, sizeof(request)) == B_OK;
}
\param type The type of report.
\param thread Receiver thread.
\return \c true on success \c false otherwise.
*/
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;
return Control(PPPC_DISABLE_REPORTS, &request, sizeof(request)) == B_OK;
}