Fixed line-endings.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34919 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,166 +1,166 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005, Ingo Weinhold <[email protected]>.
|
* Copyright 2005, Ingo Weinhold <[email protected]>.
|
||||||
* Copyright 2010, Andreas Faerber <[email protected]>
|
* Copyright 2010, Andreas Faerber <[email protected]>
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <OS.h>
|
|
||||||
|
|
||||||
#include <boot/platform.h>
|
|
||||||
#include <boot/net/Ethernet.h>
|
#include <new>
|
||||||
#include <boot/net/NetStack.h>
|
|
||||||
#include <platform/openfirmware/openfirmware.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
//#define TRACE_NETWORK
|
|
||||||
#ifdef TRACE_NETWORK
|
#include <OS.h>
|
||||||
# define TRACE(x) dprintf x
|
|
||||||
#else
|
#include <boot/platform.h>
|
||||||
# define TRACE(x) ;
|
#include <boot/net/Ethernet.h>
|
||||||
#endif
|
#include <boot/net/NetStack.h>
|
||||||
|
#include <platform/openfirmware/openfirmware.h>
|
||||||
|
|
||||||
class OFEthernetInterface : public EthernetInterface {
|
|
||||||
public:
|
//#define TRACE_NETWORK
|
||||||
OFEthernetInterface();
|
#ifdef TRACE_NETWORK
|
||||||
virtual ~OFEthernetInterface();
|
# define TRACE(x) dprintf x
|
||||||
|
#else
|
||||||
status_t Init(const char *device, const char *parameters);
|
# define TRACE(x) ;
|
||||||
|
#endif
|
||||||
virtual mac_addr_t MACAddress() const;
|
|
||||||
|
|
||||||
virtual void *AllocateSendReceiveBuffer(size_t size);
|
class OFEthernetInterface : public EthernetInterface {
|
||||||
virtual void FreeSendReceiveBuffer(void *buffer);
|
public:
|
||||||
|
OFEthernetInterface();
|
||||||
virtual ssize_t Send(const void *buffer, size_t size);
|
virtual ~OFEthernetInterface();
|
||||||
virtual ssize_t Receive(void *buffer, size_t size);
|
|
||||||
|
status_t Init(const char *device, const char *parameters);
|
||||||
private:
|
|
||||||
int fHandle;
|
virtual mac_addr_t MACAddress() const;
|
||||||
mac_addr_t fMACAddress;
|
|
||||||
};
|
virtual void *AllocateSendReceiveBuffer(size_t size);
|
||||||
|
virtual void FreeSendReceiveBuffer(void *buffer);
|
||||||
|
|
||||||
#ifdef TRACE_NETWORK
|
virtual ssize_t Send(const void *buffer, size_t size);
|
||||||
|
virtual ssize_t Receive(void *buffer, size_t size);
|
||||||
static void
|
|
||||||
hex_dump(const void *_data, int length)
|
private:
|
||||||
{
|
int fHandle;
|
||||||
uint8 *data = (uint8*)_data;
|
mac_addr_t fMACAddress;
|
||||||
for (int i = 0; i < length; i++) {
|
};
|
||||||
if (i % 4 == 0) {
|
|
||||||
if (i % 32 == 0) {
|
|
||||||
if (i != 0)
|
#ifdef TRACE_NETWORK
|
||||||
printf("\n");
|
|
||||||
printf("%03x: ", i);
|
static void
|
||||||
} else
|
hex_dump(const void *_data, int length)
|
||||||
printf(" ");
|
{
|
||||||
}
|
uint8 *data = (uint8*)_data;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
printf("%02x", data[i]);
|
if (i % 4 == 0) {
|
||||||
}
|
if (i % 32 == 0) {
|
||||||
printf("\n");
|
if (i != 0)
|
||||||
}
|
printf("\n");
|
||||||
|
printf("%03x: ", i);
|
||||||
#else // !TRACE_NETWORK
|
} else
|
||||||
|
printf(" ");
|
||||||
#define hex_dump(data, length)
|
}
|
||||||
|
|
||||||
#endif // !TRACE_NETWORK
|
printf("%02x", data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
static ip_addr_t
|
}
|
||||||
parse_ip_address(const char *string)
|
|
||||||
{
|
#else // !TRACE_NETWORK
|
||||||
ip_addr_t address = 0;
|
|
||||||
int components = 0;
|
#define hex_dump(data, length)
|
||||||
|
|
||||||
// TODO: Handles only IPv4 addresses for now.
|
#endif // !TRACE_NETWORK
|
||||||
while (components < 4) {
|
|
||||||
address |= strtol(string, NULL, 0) << ((4 - components - 1) * 8);
|
|
||||||
|
static ip_addr_t
|
||||||
const char *dot = strchr(string, '.');
|
parse_ip_address(const char *string)
|
||||||
if (dot == NULL)
|
{
|
||||||
break;
|
ip_addr_t address = 0;
|
||||||
|
int components = 0;
|
||||||
string = dot + 1;
|
|
||||||
components++;
|
// TODO: Handles only IPv4 addresses for now.
|
||||||
}
|
while (components < 4) {
|
||||||
|
address |= strtol(string, NULL, 0) << ((4 - components - 1) * 8);
|
||||||
return address;
|
|
||||||
}
|
const char *dot = strchr(string, '.');
|
||||||
|
if (dot == NULL)
|
||||||
|
break;
|
||||||
// #pragma mark -
|
|
||||||
|
string = dot + 1;
|
||||||
|
components++;
|
||||||
OFEthernetInterface::OFEthernetInterface()
|
}
|
||||||
:
|
|
||||||
EthernetInterface(),
|
return address;
|
||||||
fHandle(OF_FAILED),
|
}
|
||||||
fMACAddress(kNoMACAddress)
|
|
||||||
{
|
|
||||||
}
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
OFEthernetInterface::~OFEthernetInterface()
|
OFEthernetInterface::OFEthernetInterface()
|
||||||
{
|
:
|
||||||
if (fHandle != OF_FAILED)
|
EthernetInterface(),
|
||||||
of_close(fHandle);
|
fHandle(OF_FAILED),
|
||||||
}
|
fMACAddress(kNoMACAddress)
|
||||||
|
{
|
||||||
|
}
|
||||||
status_t
|
|
||||||
OFEthernetInterface::Init(const char *device, const char *parameters)
|
|
||||||
{
|
OFEthernetInterface::~OFEthernetInterface()
|
||||||
if (!device)
|
{
|
||||||
return B_BAD_VALUE;
|
if (fHandle != OF_FAILED)
|
||||||
|
of_close(fHandle);
|
||||||
// open device
|
}
|
||||||
fHandle = of_open(device);
|
|
||||||
if (fHandle == OF_FAILED) {
|
|
||||||
printf("opening ethernet device failed\n");
|
status_t
|
||||||
return B_ERROR;
|
OFEthernetInterface::Init(const char *device, const char *parameters)
|
||||||
}
|
{
|
||||||
|
if (!device)
|
||||||
int package = of_instance_to_package(fHandle);
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// get MAC address
|
// open device
|
||||||
int bytesRead = of_getprop(package, "local-mac-address", &fMACAddress,
|
fHandle = of_open(device);
|
||||||
sizeof(fMACAddress));
|
if (fHandle == OF_FAILED) {
|
||||||
if (bytesRead == OF_FAILED || bytesRead < (int)sizeof(fMACAddress)) {
|
printf("opening ethernet device failed\n");
|
||||||
// Failed to get the MAC address of the network device. The system may
|
return B_ERROR;
|
||||||
// have a global standard MAC address.
|
}
|
||||||
bytesRead = of_getprop(gChosen, "mac-address", &fMACAddress,
|
|
||||||
sizeof(fMACAddress));
|
int package = of_instance_to_package(fHandle);
|
||||||
if (bytesRead == OF_FAILED || bytesRead < (int)sizeof(fMACAddress)) {
|
|
||||||
printf("Failed to get MAC address\n");
|
// get MAC address
|
||||||
return B_ERROR;
|
int bytesRead = of_getprop(package, "local-mac-address", &fMACAddress,
|
||||||
}
|
sizeof(fMACAddress));
|
||||||
}
|
if (bytesRead == OF_FAILED || bytesRead < (int)sizeof(fMACAddress)) {
|
||||||
|
// Failed to get the MAC address of the network device. The system may
|
||||||
// get IP address
|
// have a global standard MAC address.
|
||||||
|
bytesRead = of_getprop(gChosen, "mac-address", &fMACAddress,
|
||||||
// Note: This is a non-standardized way. On my Mac mini the response of the
|
sizeof(fMACAddress));
|
||||||
// DHCP server is stored as property of /chosen. We try to get it and use
|
if (bytesRead == OF_FAILED || bytesRead < (int)sizeof(fMACAddress)) {
|
||||||
// the IP address we find in there.
|
printf("Failed to get MAC address\n");
|
||||||
struct {
|
return B_ERROR;
|
||||||
uint8 irrelevant[16];
|
}
|
||||||
uint32 ip_address;
|
}
|
||||||
// ...
|
|
||||||
} dhcpResponse;
|
// get IP address
|
||||||
bytesRead = of_getprop(gChosen, "dhcp-response", &dhcpResponse,
|
|
||||||
sizeof(dhcpResponse));
|
// Note: This is a non-standardized way. On my Mac mini the response of the
|
||||||
if (bytesRead != OF_FAILED && bytesRead == (int)sizeof(dhcpResponse)) {
|
// DHCP server is stored as property of /chosen. We try to get it and use
|
||||||
SetIPAddress(ntohl(dhcpResponse.ip_address));
|
// the IP address we find in there.
|
||||||
} else {
|
struct {
|
||||||
|
uint8 irrelevant[16];
|
||||||
|
uint32 ip_address;
|
||||||
|
// ...
|
||||||
|
} dhcpResponse;
|
||||||
|
bytesRead = of_getprop(gChosen, "dhcp-response", &dhcpResponse,
|
||||||
|
sizeof(dhcpResponse));
|
||||||
|
if (bytesRead != OF_FAILED && bytesRead == (int)sizeof(dhcpResponse)) {
|
||||||
|
SetIPAddress(ntohl(dhcpResponse.ip_address));
|
||||||
|
} else {
|
||||||
// try to read manual client IP from boot path
|
// try to read manual client IP from boot path
|
||||||
if (parameters != NULL) {
|
if (parameters != NULL) {
|
||||||
char *comma = strrchr(parameters, ',');
|
char *comma = strrchr(parameters, ',');
|
||||||
@@ -169,136 +169,136 @@ OFEthernetInterface::Init(const char *device, const char *parameters)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fIPAddress == 0) {
|
if (fIPAddress == 0) {
|
||||||
// try to read default-client-ip setting
|
// try to read default-client-ip setting
|
||||||
char defaultClientIP[16];
|
char defaultClientIP[16];
|
||||||
package = of_finddevice("/options");
|
package = of_finddevice("/options");
|
||||||
bytesRead = of_getprop(package, "default-client-ip",
|
bytesRead = of_getprop(package, "default-client-ip",
|
||||||
defaultClientIP, sizeof(defaultClientIP) - 1);
|
defaultClientIP, sizeof(defaultClientIP) - 1);
|
||||||
if (bytesRead != OF_FAILED && bytesRead > 1) {
|
if (bytesRead != OF_FAILED && bytesRead > 1) {
|
||||||
defaultClientIP[bytesRead] = '\0';
|
defaultClientIP[bytesRead] = '\0';
|
||||||
ip_addr_t address = parse_ip_address(defaultClientIP);
|
ip_addr_t address = parse_ip_address(defaultClientIP);
|
||||||
SetIPAddress(address);
|
SetIPAddress(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mac_addr_t
|
mac_addr_t
|
||||||
OFEthernetInterface::MACAddress() const
|
OFEthernetInterface::MACAddress() const
|
||||||
{
|
{
|
||||||
return fMACAddress;
|
return fMACAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *
|
void *
|
||||||
OFEthernetInterface::AllocateSendReceiveBuffer(size_t size)
|
OFEthernetInterface::AllocateSendReceiveBuffer(size_t size)
|
||||||
{
|
{
|
||||||
void *dmaMemory;
|
void *dmaMemory;
|
||||||
if (of_call_method(fHandle, "dma-alloc", 1, 1, size, &dmaMemory)
|
if (of_call_method(fHandle, "dma-alloc", 1, 1, size, &dmaMemory)
|
||||||
== OF_FAILED) {
|
== OF_FAILED) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return dmaMemory;
|
return dmaMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
OFEthernetInterface::FreeSendReceiveBuffer(void *buffer)
|
OFEthernetInterface::FreeSendReceiveBuffer(void *buffer)
|
||||||
{
|
{
|
||||||
if (buffer)
|
if (buffer)
|
||||||
of_call_method(fHandle, "dma-free", 1, 0, buffer);
|
of_call_method(fHandle, "dma-free", 1, 0, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
OFEthernetInterface::Send(const void *buffer, size_t size)
|
OFEthernetInterface::Send(const void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
TRACE(("OFEthernetInterface::Send(%p, %lu)\n", buffer, size));
|
TRACE(("OFEthernetInterface::Send(%p, %lu)\n", buffer, size));
|
||||||
|
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
hex_dump(buffer, size);
|
hex_dump(buffer, size);
|
||||||
|
|
||||||
int result = of_write(fHandle, buffer, size);
|
int result = of_write(fHandle, buffer, size);
|
||||||
return (result == OF_FAILED ? B_ERROR : result);
|
return (result == OF_FAILED ? B_ERROR : result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
OFEthernetInterface::Receive(void *buffer, size_t size)
|
OFEthernetInterface::Receive(void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
int result = of_read(fHandle, buffer, size);
|
int result = of_read(fHandle, buffer, size);
|
||||||
|
|
||||||
if (result != OF_FAILED && result >= 0) {
|
if (result != OF_FAILED && result >= 0) {
|
||||||
TRACE(("OFEthernetInterface::Receive(%p, %lu): received %d bytes\n",
|
TRACE(("OFEthernetInterface::Receive(%p, %lu): received %d bytes\n",
|
||||||
buffer, size, result));
|
buffer, size, result));
|
||||||
hex_dump(buffer, result);
|
hex_dump(buffer, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (result == OF_FAILED ? B_ERROR : result);
|
return (result == OF_FAILED ? B_ERROR : result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
platform_net_stack_init()
|
platform_net_stack_init()
|
||||||
{
|
{
|
||||||
// Note: At the moment we only do networking at all, if the boot device
|
// Note: At the moment we only do networking at all, if the boot device
|
||||||
// is a network device. If it isn't, we simply fail here. For serious
|
// is a network device. If it isn't, we simply fail here. For serious
|
||||||
// support we would want to iterate through the device tree and add all
|
// support we would want to iterate through the device tree and add all
|
||||||
// network devices.
|
// network devices.
|
||||||
|
|
||||||
// get boot path
|
// get boot path
|
||||||
char bootPath[192];
|
char bootPath[192];
|
||||||
int length = of_getprop(gChosen, "bootpath", bootPath, sizeof(bootPath));
|
int length = of_getprop(gChosen, "bootpath", bootPath, sizeof(bootPath));
|
||||||
if (length <= 1)
|
if (length <= 1)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// we chop off parameters; otherwise opening the network device might have
|
// we chop off parameters; otherwise opening the network device might have
|
||||||
// side effects
|
// side effects
|
||||||
char *lastComponent = strrchr(bootPath, '/');
|
char *lastComponent = strrchr(bootPath, '/');
|
||||||
char *parameters = strchr((lastComponent ? lastComponent : bootPath), ':');
|
char *parameters = strchr((lastComponent ? lastComponent : bootPath), ':');
|
||||||
if (parameters)
|
if (parameters)
|
||||||
*parameters = '\0';
|
*parameters = '\0';
|
||||||
|
|
||||||
// get device node
|
// get device node
|
||||||
int node = of_finddevice(bootPath);
|
int node = of_finddevice(bootPath);
|
||||||
if (node == OF_FAILED)
|
if (node == OF_FAILED)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// get device type
|
// get device type
|
||||||
char type[16];
|
char type[16];
|
||||||
if (of_getprop(node, "device_type", type, sizeof(type)) == OF_FAILED
|
if (of_getprop(node, "device_type", type, sizeof(type)) == OF_FAILED
|
||||||
|| strcmp("network", type) != 0) {
|
|| strcmp("network", type) != 0) {
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create an EthernetInterface object for the device
|
// create an EthernetInterface object for the device
|
||||||
OFEthernetInterface *interface = new(nothrow) OFEthernetInterface;
|
OFEthernetInterface *interface = new(nothrow) OFEthernetInterface;
|
||||||
if (!interface)
|
if (!interface)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t error = interface->Init(bootPath, parameters + 1);
|
status_t error = interface->Init(bootPath, parameters + 1);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
delete interface;
|
delete interface;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add it to the net stack
|
// add it to the net stack
|
||||||
error = NetStack::Default()->AddEthernetInterface(interface);
|
error = NetStack::Default()->AddEthernetInterface(interface);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
delete interface;
|
delete interface;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user