* Completed the previous commit and merger of the team/network/new_stack branch.
* Removed ppp_up and pppcontrol from the image for now. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18457 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_BUFFER_UTILITIES_H
|
||||
#define NET_BUFFER_UTILITIES_H
|
||||
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
|
||||
extern net_buffer_module_info *sBufferModule;
|
||||
|
||||
class NetBufferModuleGetter {
|
||||
public:
|
||||
static net_buffer_module_info *Get() { return sBufferModule; }
|
||||
};
|
||||
|
||||
//! A class to retrieve and remove a header from a buffer
|
||||
template<typename Type, typename Module = NetBufferModuleGetter > class NetBufferHeader {
|
||||
public:
|
||||
NetBufferHeader(net_buffer *buffer)
|
||||
:
|
||||
fBuffer(buffer)
|
||||
{
|
||||
}
|
||||
|
||||
~NetBufferHeader()
|
||||
{
|
||||
Remove();
|
||||
}
|
||||
|
||||
status_t
|
||||
Status()
|
||||
{
|
||||
return fBuffer->size < sizeof(Type) ? B_BAD_VALUE : B_OK;
|
||||
}
|
||||
|
||||
Type &
|
||||
Data()
|
||||
{
|
||||
Type *data;
|
||||
if (Module::Get()->direct_access(fBuffer, 0, sizeof(Type),
|
||||
(void **)&data) == B_OK)
|
||||
return *data;
|
||||
|
||||
Module::Get()->read(fBuffer, 0, &fDataBuffer, sizeof(Type));
|
||||
return fDataBuffer;
|
||||
}
|
||||
|
||||
void
|
||||
Remove()
|
||||
{
|
||||
if (fBuffer != NULL) {
|
||||
Module::Get()->remove_header(fBuffer, sizeof(Type));
|
||||
fBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Remove(size_t bytes)
|
||||
{
|
||||
if (fBuffer != NULL) {
|
||||
Module::Get()->remove_header(fBuffer, bytes);
|
||||
fBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Detach()
|
||||
{
|
||||
fBuffer = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
net_buffer *fBuffer;
|
||||
Type fDataBuffer;
|
||||
};
|
||||
|
||||
//! A class to add a header to a buffer
|
||||
template<typename Type, typename Module = NetBufferModuleGetter > class NetBufferPrepend {
|
||||
public:
|
||||
NetBufferPrepend(net_buffer *buffer)
|
||||
:
|
||||
fBuffer(buffer),
|
||||
fData(NULL)
|
||||
{
|
||||
fStatus = Module::Get()->prepend_size(buffer, sizeof(Type), (void **)&fData);
|
||||
}
|
||||
|
||||
~NetBufferPrepend()
|
||||
{
|
||||
if (fBuffer != NULL)
|
||||
Detach();
|
||||
}
|
||||
|
||||
status_t
|
||||
Status()
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
Type &
|
||||
Data()
|
||||
{
|
||||
if (fData != NULL)
|
||||
return *fData;
|
||||
|
||||
return fDataBuffer;
|
||||
}
|
||||
|
||||
// TODO: I'm not sure it's a good idea to have Detach() routines
|
||||
// in NetBufferHeader and here with such a different outcome...
|
||||
void
|
||||
Detach()
|
||||
{
|
||||
if (fData == NULL)
|
||||
Module::Get()->write(fBuffer, 0, &fDataBuffer, sizeof(Type));
|
||||
fBuffer = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
net_buffer *fBuffer;
|
||||
status_t fStatus;
|
||||
Type *fData;
|
||||
Type fDataBuffer;
|
||||
};
|
||||
|
||||
#endif // NET_BUFFER_UTILITIES_H
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_UTILITIES_H
|
||||
#define NET_UTILITIES_H
|
||||
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <net_datalink.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
class Checksum {
|
||||
public:
|
||||
struct BufferHelper {
|
||||
BufferHelper(net_buffer *_buffer, net_buffer_module_info *_bufferModule)
|
||||
: buffer(_buffer),
|
||||
bufferModule(_bufferModule)
|
||||
{
|
||||
}
|
||||
net_buffer *buffer;
|
||||
net_buffer_module_info *bufferModule;
|
||||
};
|
||||
|
||||
Checksum();
|
||||
|
||||
Checksum& operator<<(uint8 val);
|
||||
Checksum& operator<<(uint16 val);
|
||||
Checksum& operator<<(uint32 val);
|
||||
Checksum& operator<<(const BufferHelper &bufferHelper);
|
||||
|
||||
operator uint16();
|
||||
|
||||
private:
|
||||
uint32 fSum;
|
||||
};
|
||||
|
||||
inline Checksum::Checksum()
|
||||
: fSum(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline Checksum& Checksum::operator<<(uint8 _val) {
|
||||
#if B_HOST_IS_LENDIAN
|
||||
fSum += _val;
|
||||
#else
|
||||
uint16 val = _val;
|
||||
fSum += val << 8;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Checksum& Checksum::operator<<(uint16 val) {
|
||||
fSum += val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Checksum& Checksum::operator<<(uint32 val) {
|
||||
fSum += (val & 0xFFFF) + (val >> 16);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Checksum& Checksum::operator<<(const BufferHelper &bufferHelper) {
|
||||
net_buffer *buffer = bufferHelper.buffer;
|
||||
fSum += bufferHelper.bufferModule->checksum(buffer, 0, buffer->size, false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Checksum::operator uint16() {
|
||||
while (fSum >> 16) {
|
||||
fSum = (fSum & 0xffff) + (fSum >> 16);
|
||||
}
|
||||
uint16 result = (uint16)fSum;
|
||||
result ^= 0xFFFF;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// helper class that prints an address (and optionally a port) into a buffer that
|
||||
// is automatically freed at end of scope:
|
||||
class AddressString {
|
||||
public:
|
||||
inline AddressString(net_domain *domain, const sockaddr *address,
|
||||
bool printPort = false)
|
||||
: fBuffer(NULL)
|
||||
{
|
||||
domain->address_module->print_address(address, &fBuffer, printPort);
|
||||
}
|
||||
|
||||
inline AddressString(net_domain *domain, const sockaddr &address,
|
||||
bool printPort = false)
|
||||
: fBuffer(NULL)
|
||||
{
|
||||
domain->address_module->print_address(&address, &fBuffer, printPort);
|
||||
}
|
||||
|
||||
inline ~AddressString()
|
||||
{
|
||||
free(fBuffer);
|
||||
}
|
||||
|
||||
inline char *Data()
|
||||
{
|
||||
return fBuffer;
|
||||
}
|
||||
private:
|
||||
char *fBuffer;
|
||||
};
|
||||
|
||||
#endif // NET_UTILITIES_H
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ARP_CONTROL_H
|
||||
#define ARP_CONTROL_H
|
||||
|
||||
|
||||
#include <ethernet.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
||||
// ARP flags
|
||||
#define ARP_FLAG_LOCAL 0x01
|
||||
#define ARP_FLAG_REJECT 0x02
|
||||
#define ARP_FLAG_PERMANENT 0x04
|
||||
#define ARP_FLAG_PUBLISH 0x08
|
||||
|
||||
|
||||
// generic syscall interface
|
||||
#define ARP_SYSCALLS "network/arp"
|
||||
|
||||
#define ARP_SET_ENTRY 1
|
||||
#define ARP_GET_ENTRY 2
|
||||
#define ARP_GET_ENTRIES 3
|
||||
#define ARP_DELETE_ENTRY 4
|
||||
#define ARP_FLUSH_ENTRIES 5
|
||||
#define ARP_IGNORE_REPLIES 6
|
||||
|
||||
struct arp_control {
|
||||
in_addr_t address;
|
||||
uint8 ethernet_address[ETHER_ADDRESS_LENGTH];
|
||||
uint32 flags;
|
||||
uint32 cookie;
|
||||
};
|
||||
|
||||
#endif // ARP_CONTROL_H
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* ether_driver.h
|
||||
*
|
||||
* Ethernet driver: handles NE2000 and 3C503 cards
|
||||
*/
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
#ifndef _ETHER_DRIVER_H
|
||||
#define _ETHER_DRIVER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <Drivers.h>
|
||||
|
||||
/*
|
||||
* ioctls: belongs in a public header file
|
||||
* somewhere, so that the net_server and other ethernet drivers can use.
|
||||
*/
|
||||
enum {
|
||||
ETHER_GETADDR = B_DEVICE_OP_CODES_END, /* get ethernet address */
|
||||
ETHER_INIT, /* set irq and port */
|
||||
ETHER_NONBLOCK, /* set/unset nonblocking mode */
|
||||
ETHER_ADDMULTI, /* add multicast addr */
|
||||
ETHER_REMMULTI, /* rem multicast addr */
|
||||
ETHER_SETPROMISC, /* set promiscuous */
|
||||
ETHER_GETFRAMESIZE, /* get frame size */
|
||||
ETHER_ADDTIMESTAMP, /* (try to) add timestamps to packets (BONE ext) */
|
||||
ETHER_HASIOVECS, /* does the driver implement writev ? (BONE ext) (bool *) */
|
||||
ETHER_GETIFTYPE, /* get the IFT_ type of the interface (int *) */
|
||||
ETHER_GETLINKSTATE /* get line speed, quality, duplex mode, etc. */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* 48-bit ethernet address, passed back from ETHER_GETADDR
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char ebyte[6];
|
||||
} ether_address_t;
|
||||
|
||||
|
||||
/*
|
||||
* info passed to ETHER_INIT
|
||||
*/
|
||||
|
||||
typedef struct ether_init_params {
|
||||
short port;
|
||||
short irq;
|
||||
unsigned long mem;
|
||||
} ether_init_params_t;
|
||||
|
||||
/*
|
||||
* info returned from ETHER_GETLINKSTATE
|
||||
*/
|
||||
|
||||
typedef struct ether_link_state {
|
||||
float link_speed; /* In Mbits per second */
|
||||
float link_quality; /* Set to zero if not connected */
|
||||
char duplex_mode; /* Set to 1 for full duplex, 0 for half */
|
||||
} ether_link_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _ETHER_DRIVER_H */
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ETHERNET_H
|
||||
#define ETHERNET_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
#define ETHER_ADDRESS_LENGTH 6
|
||||
#define ETHER_CRC_LENGTH 4
|
||||
#define ETHER_HEADER_LENGTH 14
|
||||
|
||||
#define ETHER_MIN_FRAME_SIZE 64
|
||||
#define ETHER_MAX_FRAME_SIZE 1514
|
||||
|
||||
struct ether_header {
|
||||
uint8 destination[ETHER_ADDRESS_LENGTH];
|
||||
uint8 source[ETHER_ADDRESS_LENGTH];
|
||||
uint16 type;
|
||||
} _PACKED;
|
||||
|
||||
#define ETHER_FRAME_TYPE 0x00010000
|
||||
|
||||
// ethernet types
|
||||
#define ETHER_TYPE_IP 0x0800
|
||||
#define ETHER_TYPE_ARP 0x0806
|
||||
#define ETHER_TYPE_IPX 0x8137
|
||||
#define ETHER_TYPE_IPV6 0x86dd
|
||||
#define ETHER_TYPE_PPPOE_DISCOVERY 0x8863 // PPPoE discovery stage
|
||||
#define ETHER_TYPE_PPPOE 0x8864 // PPPoE session stage
|
||||
|
||||
#endif // ETHERNET_H
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_BUFFER_H
|
||||
#define NET_BUFFER_H
|
||||
|
||||
|
||||
#include <util/list.h>
|
||||
|
||||
#include <module.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#define NET_BUFFER_MODULE_NAME "network/stack/buffer/v1"
|
||||
|
||||
typedef struct net_buffer {
|
||||
struct list_link link;
|
||||
|
||||
// TODO: we should think about moving the address fields into the buffer data itself
|
||||
// via associated data or something like this. Or this structure as a whole, too...
|
||||
struct sockaddr_storage source;
|
||||
struct sockaddr_storage destination;
|
||||
struct net_interface *interface;
|
||||
uint32 flags;
|
||||
uint32 size;
|
||||
uint8 protocol;
|
||||
} net_buffer;
|
||||
|
||||
struct net_buffer_module_info {
|
||||
module_info info;
|
||||
|
||||
net_buffer * (*create)(size_t headerSpace);
|
||||
void (*free)(net_buffer *buffer);
|
||||
|
||||
net_buffer * (*duplicate)(net_buffer *from);
|
||||
net_buffer * (*clone)(net_buffer *from, bool shareFreeSpace);
|
||||
net_buffer * (*split)(net_buffer *from, uint32 offset);
|
||||
status_t (*merge)(net_buffer *buffer, net_buffer *with, bool after);
|
||||
|
||||
status_t (*prepend_size)(net_buffer *buffer, size_t size,
|
||||
void **_contiguousBuffer);
|
||||
status_t (*prepend)(net_buffer *buffer, const void *data,
|
||||
size_t bytes);
|
||||
status_t (*append_size)(net_buffer *buffer, size_t size,
|
||||
void **_contiguousBuffer);
|
||||
status_t (*append)(net_buffer *buffer, const void *data,
|
||||
size_t bytes);
|
||||
status_t (*insert)(net_buffer *buffer, uint32 offset,
|
||||
const void *data, size_t bytes, uint32 flags);
|
||||
status_t (*remove)(net_buffer *buffer, uint32 offset,
|
||||
size_t bytes);
|
||||
status_t (*remove_header)(net_buffer *buffer, size_t bytes);
|
||||
status_t (*remove_trailer)(net_buffer *buffer, size_t bytes);
|
||||
status_t (*trim)(net_buffer *buffer, size_t newSize);
|
||||
|
||||
status_t (*associate_data)(net_buffer *buffer, void *data);
|
||||
|
||||
status_t (*direct_access)(net_buffer *buffer, uint32 offset,
|
||||
size_t bytes, void **_data);
|
||||
status_t (*read)(net_buffer *buffer, uint32 offset, void *data,
|
||||
size_t bytes);
|
||||
status_t (*write)(net_buffer *buffer, uint32 offset,
|
||||
const void *data, size_t bytes);
|
||||
|
||||
int32 (*checksum)(net_buffer *buffer, uint32 offset, size_t bytes,
|
||||
bool finalize);
|
||||
status_t (*get_memory_map)(net_buffer *buffer,
|
||||
struct iovec *iovecs, uint32 vecCount);
|
||||
uint32 (*get_iovecs)(net_buffer *buffer,
|
||||
struct iovec *iovecs, uint32 vecCount);
|
||||
uint32 (*count_iovecs)(net_buffer *buffer);
|
||||
|
||||
void (*dump)(net_buffer *buffer);
|
||||
};
|
||||
|
||||
#endif // NET_BUFFER_H
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_DATALINK_H
|
||||
#define NET_DATALINK_H
|
||||
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <net_routing_info.h>
|
||||
|
||||
#include <util/list.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
|
||||
#define NET_DATALINK_MODULE_NAME "network/stack/datalink/v1"
|
||||
|
||||
typedef struct net_datalink_protocol net_datalink_protocol;
|
||||
|
||||
typedef struct net_domain {
|
||||
const char *name;
|
||||
int family;
|
||||
struct list interfaces;
|
||||
|
||||
struct net_protocol_module_info *module;
|
||||
struct net_address_module_info *address_module;
|
||||
} net_domain;
|
||||
|
||||
struct net_interface {
|
||||
struct list_link link;
|
||||
struct net_domain *domain;
|
||||
struct net_device *device;
|
||||
struct net_datalink_protocol *first_protocol;
|
||||
struct net_datalink_protocol_module_info *first_info;
|
||||
|
||||
char name[IF_NAMESIZE];
|
||||
struct sockaddr *address;
|
||||
struct sockaddr *destination;
|
||||
struct sockaddr *mask;
|
||||
uint32 index;
|
||||
uint32 flags;
|
||||
uint8 type;
|
||||
uint32 mtu;
|
||||
uint32 metric;
|
||||
};
|
||||
|
||||
struct net_route {
|
||||
struct sockaddr *destination;
|
||||
struct sockaddr *mask;
|
||||
struct sockaddr *gateway;
|
||||
uint32 flags;
|
||||
uint32 mtu;
|
||||
struct net_interface *interface;
|
||||
};
|
||||
|
||||
struct net_route_info {
|
||||
struct list_link link;
|
||||
struct net_route *route;
|
||||
struct sockaddr address;
|
||||
};
|
||||
|
||||
struct net_datalink_module_info {
|
||||
module_info info;
|
||||
|
||||
status_t (*control)(struct net_domain *domain, int32 option, void *value,
|
||||
size_t *_length);
|
||||
status_t (*send_data)(struct net_route *route, struct net_buffer *buffer);
|
||||
|
||||
bool (*is_local_address)(struct net_domain *domain,
|
||||
const struct sockaddr *address,
|
||||
net_interface **_interface = NULL,
|
||||
uint32 *_matchedType = NULL);
|
||||
|
||||
// routes
|
||||
status_t (*add_route)(struct net_domain *domain,
|
||||
const struct net_route *route);
|
||||
status_t (*remove_route)(struct net_domain *domain,
|
||||
const struct net_route *route);
|
||||
struct net_route *(*get_route)(struct net_domain *domain,
|
||||
const struct sockaddr *address);
|
||||
void (*put_route)(struct net_domain *domain, struct net_route *route);
|
||||
|
||||
status_t (*register_route_info)(struct net_domain *domain,
|
||||
struct net_route_info *info);
|
||||
status_t (*unregister_route_info)(struct net_domain *domain,
|
||||
struct net_route_info *info);
|
||||
status_t (*update_route_info)(struct net_domain *domain,
|
||||
struct net_route_info *info);
|
||||
};
|
||||
|
||||
struct net_address_module_info {
|
||||
module_info info;
|
||||
|
||||
status_t (*copy_address)(const sockaddr *from, sockaddr **to,
|
||||
bool replaceWithZeros = false, sockaddr *mask = NULL);
|
||||
|
||||
status_t (*mask_address)(const sockaddr *address, const sockaddr *mask,
|
||||
sockaddr *result);
|
||||
|
||||
bool (*equal_addresses)(const sockaddr *a, const sockaddr *b);
|
||||
bool (*equal_ports)(const sockaddr *a, const sockaddr *b);
|
||||
bool (*equal_addresses_and_ports)(const sockaddr *a, const sockaddr *b);
|
||||
bool (*equal_masked_addresses)(const sockaddr *a, const sockaddr *b,
|
||||
const sockaddr *mask);
|
||||
bool (*is_empty_address)(const sockaddr *address, bool checkPort = true);
|
||||
|
||||
int32 (*first_mask_bit)(sockaddr *mask);
|
||||
|
||||
bool (*check_mask)(sockaddr *address);
|
||||
|
||||
status_t (*print_address)(const sockaddr *address, char **buffer,
|
||||
bool printPort);
|
||||
|
||||
uint16 (*get_port)(const sockaddr *address);
|
||||
status_t (*set_port)(sockaddr *address, uint16 port);
|
||||
|
||||
status_t (*set_to)(sockaddr *address, const sockaddr *from);
|
||||
status_t (*set_to_empty_address)(sockaddr *address);
|
||||
|
||||
uint32 (*hash_address_pair)(const sockaddr *ourAddress,
|
||||
const sockaddr *peerAddress);
|
||||
|
||||
status_t (*checksum_address)(struct Checksum *checksum,
|
||||
const sockaddr *address);
|
||||
|
||||
bool (*matches_broadcast_address)(const sockaddr *address,
|
||||
const sockaddr *mask, const sockaddr *broadcastAddr);
|
||||
};
|
||||
|
||||
#endif // NET_DATALINK_H
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_DATALINK_PROTOCOL_H
|
||||
#define NET_DATALINK_PROTOCOL_H
|
||||
|
||||
|
||||
#include <net_buffer.h>
|
||||
|
||||
|
||||
typedef struct net_datalink_protocol {
|
||||
struct net_datalink_protocol *next;
|
||||
struct net_datalink_protocol_module_info *module;
|
||||
struct net_interface *interface;
|
||||
} net_datalink_protocol;
|
||||
|
||||
struct net_datalink_protocol_module_info {
|
||||
module_info info;
|
||||
|
||||
status_t (*init_protocol)(struct net_interface *interface,
|
||||
net_datalink_protocol **_protocol);
|
||||
status_t (*uninit_protocol)(net_datalink_protocol *self);
|
||||
|
||||
status_t (*send_data)(net_datalink_protocol *self,
|
||||
net_buffer *buffer);
|
||||
|
||||
status_t (*interface_up)(net_datalink_protocol *self);
|
||||
void (*interface_down)(net_datalink_protocol *self);
|
||||
|
||||
status_t (*control)(net_datalink_protocol *self,
|
||||
int32 op, void *argument, size_t length);
|
||||
};
|
||||
|
||||
#endif // NET_DATALINK_PROTOCOL_H
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_DEVICE_H
|
||||
#define NET_DEVICE_H
|
||||
|
||||
|
||||
#include <module.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
|
||||
struct net_hardware_address {
|
||||
uint8 data[64];
|
||||
uint8 length;
|
||||
};
|
||||
|
||||
struct net_device {
|
||||
struct net_device_module_info *module;
|
||||
|
||||
char name[IF_NAMESIZE];
|
||||
uint32 index;
|
||||
uint32 flags; // IFF_LOOPBACK, ...
|
||||
uint32 type; // IFT_ETHER, ...
|
||||
size_t mtu;
|
||||
uint32 media;
|
||||
size_t header_length;
|
||||
|
||||
struct net_hardware_address address;
|
||||
|
||||
ifreq_stats stats;
|
||||
};
|
||||
|
||||
struct net_device_module_info {
|
||||
struct module_info info;
|
||||
|
||||
status_t (*init_device)(const char *name, struct net_device **_device);
|
||||
status_t (*uninit_device)(struct net_device *device);
|
||||
|
||||
status_t (*up)(struct net_device *device);
|
||||
void (*down)(struct net_device *device);
|
||||
|
||||
status_t (*control)(struct net_device *device, int32 op,
|
||||
void *argument, size_t length);
|
||||
|
||||
status_t (*send_data)(struct net_device *device, struct net_buffer *buffer);
|
||||
status_t (*receive_data)(struct net_device *device, struct net_buffer **_buffer);
|
||||
|
||||
status_t (*set_mtu)(struct net_device *device, size_t mtu);
|
||||
status_t (*set_promiscuous)(struct net_device *device, bool promiscuous);
|
||||
status_t (*set_media)(struct net_device *device, uint32 media);
|
||||
|
||||
status_t (*get_multicast_addrs)(struct net_device *device,
|
||||
net_hardware_address **addressArray, uint32 count);
|
||||
status_t (*set_multicast_addrs)(struct net_device *device,
|
||||
const net_hardware_address **addressArray, uint32 count);
|
||||
};
|
||||
|
||||
#endif // NET_DEVICE_H
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_PROTOCOL_H
|
||||
#define NET_PROTOCOL_H
|
||||
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <net_socket.h>
|
||||
|
||||
|
||||
// level flags to pass to control()
|
||||
#define LEVEL_SET_OPTION 0x10000000
|
||||
#define LEVEL_GET_OPTION 0x20000000
|
||||
#define LEVEL_DRIVER_IOCTL 0x0f000000
|
||||
#define LEVEL_MASK 0x0fffffff
|
||||
|
||||
typedef struct net_protocol {
|
||||
struct net_protocol *next;
|
||||
struct net_protocol_module_info *module;
|
||||
net_socket *socket;
|
||||
} net_protocol;
|
||||
|
||||
struct net_protocol_module_info {
|
||||
module_info info;
|
||||
|
||||
net_protocol *(*init_protocol)(net_socket *socket);
|
||||
status_t (*uninit_protocol)(net_protocol *self);
|
||||
|
||||
status_t (*open)(net_protocol *self);
|
||||
status_t (*close)(net_protocol *self);
|
||||
status_t (*free)(net_protocol *self);
|
||||
|
||||
status_t (*connect)(net_protocol *self, const struct sockaddr *address);
|
||||
status_t (*accept)(net_protocol *self, struct net_socket **_acceptedSocket);
|
||||
status_t (*control)(net_protocol *self, int level, int option, void *value,
|
||||
size_t *_length);
|
||||
|
||||
status_t (*bind)(net_protocol *self, struct sockaddr *address);
|
||||
status_t (*unbind)(net_protocol *self, struct sockaddr *address);
|
||||
status_t (*listen)(net_protocol *self, int count);
|
||||
status_t (*shutdown)(net_protocol *self, int direction);
|
||||
|
||||
status_t (*send_data)(net_protocol *self, net_buffer *buffer);
|
||||
status_t (*send_routed_data)(net_protocol *self,
|
||||
struct net_route *route, net_buffer *buffer);
|
||||
ssize_t (*send_avail)(net_protocol *self);
|
||||
|
||||
status_t (*read_data)(net_protocol *self, size_t numBytes, uint32 flags,
|
||||
net_buffer **_buffer);
|
||||
ssize_t (*read_avail)(net_protocol *self);
|
||||
|
||||
struct net_domain *(*get_domain)(net_protocol *self);
|
||||
size_t (*get_mtu)(net_protocol *self, const struct sockaddr *address);
|
||||
|
||||
status_t (*receive_data)(net_buffer *data);
|
||||
status_t (*error)(uint32 code, net_buffer *data);
|
||||
|
||||
status_t (*error_reply)(net_protocol *self, net_buffer *causedError,
|
||||
uint32 code, void *errorData);
|
||||
};
|
||||
|
||||
#endif // NET_PROTOCOL_H
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_ROUTING_INFO_H
|
||||
#define NET_ROUTING_INFO_H
|
||||
|
||||
|
||||
struct net_routing_info {
|
||||
void *root;
|
||||
void *default_route;
|
||||
|
||||
int addr_start;
|
||||
int addr_end;
|
||||
};
|
||||
|
||||
#endif // NET_ROUTING_INFO_H
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_SOCKET_H
|
||||
#define NET_SOCKET_H
|
||||
|
||||
|
||||
#include <net_buffer.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#define NET_SOCKET_MODULE_NAME "network/stack/socket/v1"
|
||||
|
||||
typedef struct net_socket {
|
||||
struct net_protocol *first_protocol;
|
||||
struct net_protocol_module_info *first_info;
|
||||
|
||||
int family;
|
||||
int type;
|
||||
int protocol;
|
||||
|
||||
struct sockaddr_storage address;
|
||||
struct sockaddr_storage peer;
|
||||
|
||||
int options;
|
||||
int linger;
|
||||
|
||||
struct {
|
||||
uint32 buffer_size;
|
||||
uint32 low_water_mark;
|
||||
bigtime_t timeout;
|
||||
} send, receive;
|
||||
} net_socket;
|
||||
|
||||
struct net_socket_module_info {
|
||||
struct module_info info;
|
||||
|
||||
status_t (*socket)(int family, int type, int protocol, net_socket **_socket);
|
||||
status_t (*close)(net_socket *socket);
|
||||
status_t (*free)(net_socket *socket);
|
||||
|
||||
status_t (*readv)(net_socket *socket, const iovec *vecs, size_t vecCount,
|
||||
size_t *_length);
|
||||
status_t (*writev)(net_socket *socket, const iovec *vecs, size_t vecCount,
|
||||
size_t *_length);
|
||||
status_t (*control)(net_socket *socket, int32 op, void *data, size_t length);
|
||||
|
||||
ssize_t (*read_avail)(net_socket *socket);
|
||||
ssize_t (*send_avail)(net_socket *socket);
|
||||
|
||||
status_t (*send_data)(net_socket *socket, net_buffer *buffer);
|
||||
status_t (*receive_data)(net_socket *socket, size_t length, uint32 flags,
|
||||
net_buffer **_buffer);
|
||||
|
||||
// standard socket API
|
||||
int (*accept)(net_socket *socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength, net_socket **_acceptedSocket);
|
||||
int (*bind)(net_socket *socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
int (*connect)(net_socket *socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
int (*getpeername)(net_socket *socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
int (*getsockname)(net_socket *socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
int (*getsockopt)(net_socket *socket, int level, int option,
|
||||
void *optionValue, int *_optionLength);
|
||||
int (*listen)(net_socket *socket, int backlog);
|
||||
ssize_t (*recv)(net_socket *socket, void *data, size_t length, int flags);
|
||||
ssize_t (*recvfrom)(net_socket *socket, void *data, size_t length, int flags,
|
||||
struct sockaddr *address, socklen_t *_addressLength);
|
||||
ssize_t (*send)(net_socket *socket, const void *data, size_t length, int flags);
|
||||
ssize_t (*sendto)(net_socket *socket, const void *data, size_t length,
|
||||
int flags, const struct sockaddr *address, socklen_t addressLength);
|
||||
int (*setsockopt)(net_socket *socket, int level, int option,
|
||||
const void *optionValue, int optionLength);
|
||||
int (*shutdown)(net_socket *socket, int direction);
|
||||
};
|
||||
|
||||
#endif // NET_SOCKET_H
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_STACK_H
|
||||
#define NET_STACK_H
|
||||
|
||||
|
||||
#include <lock.h>
|
||||
#include <util/list.h>
|
||||
|
||||
#include <module.h>
|
||||
|
||||
|
||||
#define NET_STACK_MODULE_NAME "network/stack/v1"
|
||||
|
||||
struct net_fifo {
|
||||
benaphore lock;
|
||||
sem_id notify;
|
||||
int32 waiting;
|
||||
|
||||
size_t max_bytes;
|
||||
size_t current_bytes;
|
||||
|
||||
struct list buffers;
|
||||
};
|
||||
|
||||
typedef void (*net_timer_func)(struct net_timer *timer, void *data);
|
||||
|
||||
struct net_timer {
|
||||
struct list_link link;
|
||||
net_timer_func hook;
|
||||
void *data;
|
||||
bigtime_t due;
|
||||
};
|
||||
|
||||
typedef int32 (*net_deframe_func)(struct net_device *device, struct net_buffer *buffer);
|
||||
typedef status_t (*net_receive_func)(void *cookie, struct net_buffer *buffer);
|
||||
|
||||
struct net_stack_module_info {
|
||||
module_info info;
|
||||
|
||||
status_t (*register_domain)(int family, const char *name,
|
||||
struct net_protocol_module_info *module,
|
||||
struct net_address_module_info *addressModule,
|
||||
struct net_domain **_domain);
|
||||
status_t (*unregister_domain)(struct net_domain *domain);
|
||||
struct net_domain *(*get_domain)(int family);
|
||||
|
||||
status_t (*register_domain_protocols)(int family, int type, int protocol, ...);
|
||||
status_t (*register_domain_datalink_protocols)(int family, int type, ...);
|
||||
status_t (*register_domain_receiving_protocol)(int family, int type,
|
||||
const char *moduleName);
|
||||
|
||||
status_t (*get_domain_receiving_protocol)(struct net_domain *domain, uint32 type,
|
||||
struct net_protocol_module_info **_module);
|
||||
status_t (*put_domain_receiving_protocol)(struct net_domain *domain, uint32 type);
|
||||
|
||||
// devices
|
||||
status_t (*register_device_deframer)(struct net_device *device,
|
||||
net_deframe_func deframeFunc);
|
||||
status_t (*unregister_device_deframer)(struct net_device *device);
|
||||
|
||||
status_t (*register_domain_device_handler)(struct net_device *device,
|
||||
int32 type, struct net_domain *domain);
|
||||
status_t (*register_device_handler)(struct net_device *device, int32 type,
|
||||
net_receive_func receiveFunc, void *cookie);
|
||||
status_t (*unregister_device_handler)(struct net_device *device, int32 type);
|
||||
|
||||
status_t (*register_device_monitor)(struct net_device *device,
|
||||
net_receive_func receiveFunc, void *cookie);
|
||||
status_t (*unregister_device_monitor)(struct net_device *device,
|
||||
net_receive_func receiveFunc, void *cookie);
|
||||
|
||||
status_t (*device_removed)(struct net_device *device);
|
||||
|
||||
// Utility Functions
|
||||
|
||||
// checksum
|
||||
uint16 (*checksum)(uint8 *buffer, size_t length);
|
||||
|
||||
// fifo
|
||||
status_t (*init_fifo)(struct net_fifo *fifo, const char *name, size_t maxBytes);
|
||||
void (*uninit_fifo)(struct net_fifo *fifo);
|
||||
status_t (*fifo_enqueue_buffer)(struct net_fifo *fifo, struct net_buffer *buffer);
|
||||
ssize_t (*fifo_dequeue_buffer)(struct net_fifo *fifo, uint32 flags,
|
||||
bigtime_t timeout, struct net_buffer **_buffer);
|
||||
status_t (*clear_fifo)(struct net_fifo *fifo);
|
||||
|
||||
// timer
|
||||
void (*init_timer)(struct net_timer *timer, net_timer_func hook, void *data);
|
||||
void (*set_timer)(struct net_timer *timer, bigtime_t delay);
|
||||
};
|
||||
|
||||
#endif // NET_STACK_H
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2002-2006, Haiku, Inc. All Rights Reserved.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_STACK_DRIVER_H
|
||||
#define NET_STACK_DRIVER_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
// Forward declaration
|
||||
struct sockaddr;
|
||||
|
||||
#define NET_STACK_DRIVER_DEV "net/stack"
|
||||
#define NET_STACK_DRIVER_PATH "/dev/" NET_STACK_DRIVER_DEV
|
||||
|
||||
enum {
|
||||
NET_STACK_IOCTL_BASE = 8800,
|
||||
NET_STACK_IOCTL_END = 8999,
|
||||
|
||||
// ops not acting on an existing socket
|
||||
NET_STACK_SOCKET = NET_STACK_IOCTL_BASE, // socket_args *
|
||||
NET_STACK_GET_COOKIE, // void **
|
||||
NET_STACK_CONTROL_NET_MODULE, // control_net_module_args *
|
||||
NET_STACK_SYSCTL, // sysctl_args *
|
||||
|
||||
// ops acting on an existing socket
|
||||
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_SOCKETPAIR, // socketpair_args *
|
||||
|
||||
// TODO: remove R5 select() emulation
|
||||
NET_STACK_SELECT, // select_args *
|
||||
NET_STACK_DESELECT, // select_args *
|
||||
|
||||
NET_STACK_NOTIFY_SOCKET_EVENT, // notify_socket_event_args * (userland stack only)
|
||||
|
||||
NET_STACK_IOCTL_MAX
|
||||
};
|
||||
|
||||
struct sockaddr_args { // used by NET_STACK_CONNECT/_BIND/_GETSOCKNAME/_GETPEERNAME
|
||||
struct sockaddr *address;
|
||||
socklen_t address_length;
|
||||
};
|
||||
|
||||
struct sockopt_args { // used by NET_STACK_SETSOCKOPT/_GETSOCKOPT
|
||||
int level;
|
||||
int option;
|
||||
void *value;
|
||||
int length;
|
||||
};
|
||||
|
||||
struct transfer_args { // used by NET_STACK_SEND/_RECV
|
||||
void *data;
|
||||
size_t data_length;
|
||||
int flags;
|
||||
struct sockaddr *address; // only used for recvfrom() and sendto()
|
||||
socklen_t address_length; // ""
|
||||
};
|
||||
|
||||
struct socket_args { // used by NET_STACK_SOCKET
|
||||
int family;
|
||||
int type;
|
||||
int protocol;
|
||||
};
|
||||
|
||||
struct socketpair_args { // used by NET_STACK_SOCKETPAIR
|
||||
void *cookie;
|
||||
};
|
||||
|
||||
struct accept_args { // used by NET_STACK_ACCEPT
|
||||
void *cookie;
|
||||
struct sockaddr *address;
|
||||
socklen_t address_length;
|
||||
};
|
||||
|
||||
struct sysctl_args { // used by NET_STACK_SYSCTL
|
||||
int *name;
|
||||
uint namelen;
|
||||
void *oldp;
|
||||
size_t *oldlenp;
|
||||
void *newp;
|
||||
size_t newlen;
|
||||
};
|
||||
|
||||
struct control_net_module_args { // used by NET_STACK_CONTROL_NET_MODULE
|
||||
const char *name;
|
||||
uint32 op;
|
||||
void *data;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
/*
|
||||
Userland stack driver on_socket_event() callback mecanism implementation:
|
||||
the driver start a kernel thread waiting on a port for
|
||||
a NET_STACK_SOCKET_EVENT_MSG message, which come with a socket_event_data block.
|
||||
|
||||
The on_socket_event() mechanism stay in driver (kernelland) because it's
|
||||
only there we can call kernel's notify_select_event() on BONE systems.
|
||||
For non-BONE systems, we use our own r5_notify_select_event()
|
||||
implementation, that could be moved into the userland net_server code,
|
||||
but it'll have split (again!) the /dev/net/stack driver code...
|
||||
*/
|
||||
|
||||
struct notify_socket_event_args { // used by NET_STACK_NOTIFY_SOCKET_EVENT
|
||||
port_id notify_port; // port waiting for notification, -1 = stop notify
|
||||
void *cookie; // this cookie value will be pass back in the socket_event_args
|
||||
};
|
||||
|
||||
#define NET_STACK_SOCKET_EVENT_NOTIFICATION 'sevn'
|
||||
|
||||
struct socket_event_data {
|
||||
uint32 event; // B_SELECT_READ, B_SELECT_WRITE or B_SELECT_ERROR
|
||||
void *cookie; // The cookie as set in notify_socket_event_args for this socket
|
||||
};
|
||||
|
||||
/*
|
||||
R5.0.3 and before select() kernel support is too buggy to be used, so
|
||||
here are the structures we used to support select() on sockets, and *only* on
|
||||
sockets!
|
||||
*/
|
||||
|
||||
struct select_args { // used by NET_STACK_SELECT and NET_STACK_DESELECT
|
||||
struct selectsync *sync; // in fact, it's the area_id of a r5_selectsync struct!!!
|
||||
uint32 ref;
|
||||
};
|
||||
|
||||
struct r5_selectsync {
|
||||
sem_id lock; // lock this r5_selectsync
|
||||
sem_id wakeup; // sem to release to wakeup select()
|
||||
struct fd_set rbits; // read event bits field
|
||||
struct fd_set wbits; // write event bits field
|
||||
struct fd_set ebits; // exception event bits field
|
||||
};
|
||||
|
||||
#endif /* NET_STACK_DRIVER_H */
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2002-2006, Haiku, Inc. All Rights Reserved.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef USERLAND_IPC_H
|
||||
#define USERLAND_IPC_H
|
||||
|
||||
/*! userland_ipc - Communication between the network driver
|
||||
and the userland stack.
|
||||
*/
|
||||
|
||||
#include <OS.h>
|
||||
#include <Drivers.h>
|
||||
|
||||
#include "net_stack_driver.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NET_STACK_PORTNAME "net_server connection"
|
||||
|
||||
enum {
|
||||
NET_STACK_OPEN = NET_STACK_IOCTL_MAX,
|
||||
NET_STACK_CLOSE,
|
||||
NET_STACK_NEW_CONNECTION,
|
||||
};
|
||||
|
||||
#define MAX_NET_AREAS 16
|
||||
|
||||
typedef struct {
|
||||
area_id id;
|
||||
uint8 *offset;
|
||||
} net_area_info;
|
||||
|
||||
typedef struct {
|
||||
int32 op;
|
||||
// int32 buffer;
|
||||
uint8 *data;
|
||||
int32 length;
|
||||
int32 result;
|
||||
net_area_info area[MAX_NET_AREAS];
|
||||
} net_command;
|
||||
|
||||
#define CONNECTION_QUEUE_LENGTH 128
|
||||
#define CONNECTION_COMMAND_SIZE 2048
|
||||
|
||||
typedef struct {
|
||||
port_id port;
|
||||
area_id area;
|
||||
thread_id socket_thread;
|
||||
|
||||
sem_id commandSemaphore; // command queue
|
||||
uint32 numCommands,bufferSize;
|
||||
} net_connection;
|
||||
|
||||
|
||||
extern status_t init_userland_ipc(void);
|
||||
extern void shutdown_userland_ipc(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* USERLAND_IPC_H */
|
||||
Reference in New Issue
Block a user