From fe54eece9d76dd4a88beb5920056793ee4714461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 21 Oct 2007 10:58:24 +0000 Subject: [PATCH] * Removed the "new_stack" test approach; it's no longer useful, and you can still look for it in the SVN history if you like. * Moved tcp_tester.cpp to its own sub-directory tcp_shell - it doesn't yet build, though (due to recent changes to the stack/TCP implementation). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22631 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/net/Jamfile | 54 +- src/tests/kits/net/new_stack/Jamfile | 52 - src/tests/kits/net/new_stack/atomizer/Jamfile | 8 - src/tests/kits/net/new_stack/framings/Jamfile | 3 - .../net/new_stack/framings/ethernet/Jamfile | 8 - .../framings/ethernet/ethernet_frame.c | 175 --- .../kits/net/new_stack/headers/memory_pool.h | 38 - .../kits/net/new_stack/headers/net_stack.h | 190 ---- .../kits/net/new_stack/interfaces/Jamfile | 5 - .../interfaces/ether_drivers/Jamfile | 8 - .../interfaces/ether_drivers/ether_drivers.c | 356 ------ .../net/new_stack/interfaces/loopback/Jamfile | 8 - .../new_stack/interfaces/loopback/loopback.c | 96 -- .../kits/net/new_stack/memory_pool/Jamfile | 8 - .../net/new_stack/memory_pool/memory_pool.c | 295 ----- .../kits/net/new_stack/net_stack_server.cpp | 120 -- .../kits/net/new_stack/protocols/Jamfile | 5 - .../kits/net/new_stack/protocols/arp/Jamfile | 8 - .../kits/net/new_stack/protocols/arp/arp.c | 219 ---- .../kits/net/new_stack/protocols/ipv4/Jamfile | 8 - .../kits/net/new_stack/protocols/ipv4/ipv4.c | 203 ---- src/tests/kits/net/new_stack/stack/Jamfile | 13 - .../kits/net/new_stack/stack/attribute.c | 210 ---- .../kits/net/new_stack/stack/attribute.h | 48 - src/tests/kits/net/new_stack/stack/buffer.c | 1012 ----------------- src/tests/kits/net/new_stack/stack/buffer.h | 54 - src/tests/kits/net/new_stack/stack/dump.c | 51 - src/tests/kits/net/new_stack/stack/dump.h | 8 - .../kits/net/new_stack/stack/layers_manager.c | 469 -------- .../kits/net/new_stack/stack/layers_manager.h | 35 - src/tests/kits/net/new_stack/stack/stack.c | 212 ---- src/tests/kits/net/new_stack/stack/stack.h | 9 - src/tests/kits/net/new_stack/stack/timer.c | 277 ----- src/tests/kits/net/new_stack/stack/timer.h | 37 - src/tests/kits/net/new_stack/userland_ipc.c | 554 --------- src/tests/kits/net/new_stack/userland_ipc.h | 62 - .../kits/net/new_stack/userland_modules.cpp | 869 -------------- src/tests/kits/net/tcp_shell/Jamfile | 45 + .../kits/net/{ => tcp_shell}/tcp_tester.cpp | 0 39 files changed, 46 insertions(+), 5786 deletions(-) delete mode 100644 src/tests/kits/net/new_stack/Jamfile delete mode 100644 src/tests/kits/net/new_stack/atomizer/Jamfile delete mode 100644 src/tests/kits/net/new_stack/framings/Jamfile delete mode 100644 src/tests/kits/net/new_stack/framings/ethernet/Jamfile delete mode 100644 src/tests/kits/net/new_stack/framings/ethernet/ethernet_frame.c delete mode 100644 src/tests/kits/net/new_stack/headers/memory_pool.h delete mode 100644 src/tests/kits/net/new_stack/headers/net_stack.h delete mode 100644 src/tests/kits/net/new_stack/interfaces/Jamfile delete mode 100644 src/tests/kits/net/new_stack/interfaces/ether_drivers/Jamfile delete mode 100644 src/tests/kits/net/new_stack/interfaces/ether_drivers/ether_drivers.c delete mode 100644 src/tests/kits/net/new_stack/interfaces/loopback/Jamfile delete mode 100644 src/tests/kits/net/new_stack/interfaces/loopback/loopback.c delete mode 100644 src/tests/kits/net/new_stack/memory_pool/Jamfile delete mode 100644 src/tests/kits/net/new_stack/memory_pool/memory_pool.c delete mode 100644 src/tests/kits/net/new_stack/net_stack_server.cpp delete mode 100644 src/tests/kits/net/new_stack/protocols/Jamfile delete mode 100644 src/tests/kits/net/new_stack/protocols/arp/Jamfile delete mode 100644 src/tests/kits/net/new_stack/protocols/arp/arp.c delete mode 100644 src/tests/kits/net/new_stack/protocols/ipv4/Jamfile delete mode 100644 src/tests/kits/net/new_stack/protocols/ipv4/ipv4.c delete mode 100644 src/tests/kits/net/new_stack/stack/Jamfile delete mode 100644 src/tests/kits/net/new_stack/stack/attribute.c delete mode 100644 src/tests/kits/net/new_stack/stack/attribute.h delete mode 100644 src/tests/kits/net/new_stack/stack/buffer.c delete mode 100644 src/tests/kits/net/new_stack/stack/buffer.h delete mode 100644 src/tests/kits/net/new_stack/stack/dump.c delete mode 100644 src/tests/kits/net/new_stack/stack/dump.h delete mode 100644 src/tests/kits/net/new_stack/stack/layers_manager.c delete mode 100644 src/tests/kits/net/new_stack/stack/layers_manager.h delete mode 100644 src/tests/kits/net/new_stack/stack/stack.c delete mode 100644 src/tests/kits/net/new_stack/stack/stack.h delete mode 100644 src/tests/kits/net/new_stack/stack/timer.c delete mode 100644 src/tests/kits/net/new_stack/stack/timer.h delete mode 100644 src/tests/kits/net/new_stack/userland_ipc.c delete mode 100644 src/tests/kits/net/new_stack/userland_ipc.h delete mode 100644 src/tests/kits/net/new_stack/userland_modules.cpp create mode 100644 src/tests/kits/net/tcp_shell/Jamfile rename src/tests/kits/net/{ => tcp_shell}/tcp_tester.cpp (100%) diff --git a/src/tests/kits/net/Jamfile b/src/tests/kits/net/Jamfile index 21b40f5804..2e41d915be 100644 --- a/src/tests/kits/net/Jamfile +++ b/src/tests/kits/net/Jamfile @@ -2,22 +2,6 @@ SubDir HAIKU_TOP src tests kits net ; SetSubDirSupportedPlatformsBeOSCompatible ; -SubDirHdrs [ FDirName $(HAIKU_TOP) src tests add-ons kernel file_systems fs_shell ] ; -SubDirHdrs [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols tcp ] ; -SubDirHdrs [ FDirName $(HAIKU_TOP) src add-ons kernel network stack ] ; -UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; -UsePrivateHeaders net ; - -# bonefish: Tried to get the first test compiling. It complained about not -# being able to find some headers, thus I added the respective include dirs -# until it was asking for headers we currently don't have -# (sys/select.h, sys/sockio.h). - -#SubDirHdrs [ FDirName $(HAIKU_TOP) headers posix sys ] ; -#SubDirHdrs [ FDirName $(HAIKU_TOP) headers posix net ] ; -#UsePrivateHeaders kernel ; -#UseArchHeaders $(TARGET_ARCH) ; - SimpleTest udp_client : udp_client.c : $(TARGET_NETWORK_LIBS) ; SimpleTest udp_echo : udp_echo.c : $(TARGET_NETWORK_LIBS) ; SimpleTest udp_server : udp_server.c : $(TARGET_NETWORK_LIBS) ; @@ -25,45 +9,9 @@ SimpleTest udp_server : udp_server.c : $(TARGET_NETWORK_LIBS) ; SimpleTest tcp_server : tcp_server.c : $(TARGET_NETWORK_LIBS) ; SimpleTest tcp_client : tcp_client.c : $(TARGET_NETWORK_LIBS) ; -SimpleTest tcp_tester : - tcp_tester.cpp - - # stack - net_buffer.cpp - utility.cpp - - # tcp - tcp.cpp - TCPEndpoint.cpp - BufferQueue.cpp - EndpointManager.cpp - - # misc - argv.c - ipv4_address.cpp - - : be libkernelland_emu.so -; - -SEARCH on [ FGristFiles - tcp.cpp TCPEndpoint.cpp BufferQueue.cpp EndpointManager.cpp - ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols tcp ] ; - -SEARCH on [ FGristFiles - ipv4_address.cpp - ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols ipv4 ] ; - -SEARCH on [ FGristFiles - net_buffer.cpp utility.cpp - ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network stack ] ; - -SEARCH on [ FGristFiles - argv.c - ] = [ FDirName $(HAIKU_TOP) src tests add-ons kernel file_systems fs_shell ] ; - SubInclude HAIKU_TOP src tests kits net DialUpPreflet ; SubInclude HAIKU_TOP src tests kits net multicast ; SubInclude HAIKU_TOP src tests kits net netperf ; -# SubInclude HAIKU_TOP src tests kits net new_stack ; SubInclude HAIKU_TOP src tests kits net preflet ; +SubInclude HAIKU_TOP src tests kits net tcp_shell ; SubInclude HAIKU_TOP src tests kits net tcptester ; diff --git a/src/tests/kits/net/new_stack/Jamfile b/src/tests/kits/net/new_stack/Jamfile deleted file mode 100644 index 8b5177a3c9..0000000000 --- a/src/tests/kits/net/new_stack/Jamfile +++ /dev/null @@ -1,52 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack ; - -UseHeaders [ FDirName $(HAIKU_TOP) src tests kits net new_stack headers ] ; - -SimpleTest new_stack_tester : - net_stack_server.cpp - userland_modules.cpp - : be -; - -{ - # symlink the userland add-ons dir to the dir where the net_stack_tester - # lives - local dir = [ on new_stack_tester return $(LOCATE) ] ; -# TODO: We don't have a "distro" tree (including the add-on dir) anymore. -# MakeLocate userland : $(HAIKU_ADDON_DIR) ; -# MakeLocate add-ons : $(dir) ; -# RelSymLink add-ons : userland : false ; - - # alias for the stack_tester the modules link against - LOCATE on new_stack_tester = $(dir) ; -# Depends new_stack_tester : add-ons ; -} - -# for convenience: this target builds all userland new_stack modules -NotFile userland_network_v2_modules ; -Depends userland_network_v2_modules : - # the main stack modules - stack - memory_pool - atomizer - - # framing modules - ethernet_frame - - # interfaces modules - loopback - ether_drivers - - # protocols modules - arp - ipv4 -; - - -SubInclude HAIKU_TOP src tests kits net new_stack memory_pool ; -SubInclude HAIKU_TOP src tests kits net new_stack atomizer ; -SubInclude HAIKU_TOP src tests kits net new_stack stack ; -SubInclude HAIKU_TOP src tests kits net new_stack interfaces ; -SubInclude HAIKU_TOP src tests kits net new_stack protocols ; -SubInclude HAIKU_TOP src tests kits net new_stack framings ; -# SubInclude HAIKU_TOP src tests kits net new_stack ppp ; diff --git a/src/tests/kits/net/new_stack/atomizer/Jamfile b/src/tests/kits/net/new_stack/atomizer/Jamfile deleted file mode 100644 index d9ea351cda..0000000000 --- a/src/tests/kits/net/new_stack/atomizer/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack atomizer ; - -SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons kernel generic atomizer ] ; - -Addon atomizer : - atomizer.c - : new_stack_tester -; diff --git a/src/tests/kits/net/new_stack/framings/Jamfile b/src/tests/kits/net/new_stack/framings/Jamfile deleted file mode 100644 index 2b36ac8614..0000000000 --- a/src/tests/kits/net/new_stack/framings/Jamfile +++ /dev/null @@ -1,3 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack framings ; - -SubInclude HAIKU_TOP src tests kits net new_stack framings ethernet ; diff --git a/src/tests/kits/net/new_stack/framings/ethernet/Jamfile b/src/tests/kits/net/new_stack/framings/ethernet/Jamfile deleted file mode 100644 index 9b8f6ca51d..0000000000 --- a/src/tests/kits/net/new_stack/framings/ethernet/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack framings ethernet ; - -UseHeaders [ FDirName $(HAIKU_TOP) src tests kits net new_stack headers ] ; - -Addon ethernet_frame : - ethernet_frame.c - : new_stack_tester be -; diff --git a/src/tests/kits/net/new_stack/framings/ethernet/ethernet_frame.c b/src/tests/kits/net/new_stack/framings/ethernet/ethernet_frame.c deleted file mode 100644 index a001b9ee3a..0000000000 --- a/src/tests/kits/net/new_stack/framings/ethernet/ethernet_frame.c +++ /dev/null @@ -1,175 +0,0 @@ -/* ethernet_framer.c - ethernet framing layer module - */ - -#include -#include -#include -#include - -#include -#include - -#include "net_stack.h" - -#define ETHER_ADDR_LEN 6 /* Ethernet address length */ -#define ETHER_TYPE_LEN 2 /* Ethernet type field length */ -#define ETHER_CRC_LEN 4 /* Ethernet CRC lenght */ -#define ETHER_HDR_LEN ((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN) -#define ETHER_MIN_LEN 64 /* Minimum frame length, CRC included */ -#define ETHER_MAX_LEN 1518 /* Maximum frame length, CRC included */ - -#define ETHERMTU (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) -#define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) - -typedef struct ethernet_addr { - uint8 byte[ETHER_ADDR_LEN]; -} ethernet_addr; - - -typedef struct ethernet2_header { - ethernet_addr dst; - ethernet_addr src; - uint16 type; -} ethernet2_header; - - - -status_t std_ops(int32 op, ...); - -struct net_layer_module_info nlmi; - -static struct net_stack_module_info *g_stack = NULL; - -string_token ethernet_header_attr; -string_token ethernet_from_attr; -string_token ethernet_to_attr; -string_token ethernet_protocol_attr; - - -static void dump_ethernet(net_buffer *buffer) -{ - ethernet2_header hdr; - const char *pname; - - g_stack->read_buffer(buffer, 0, &hdr, sizeof(hdr)); - - switch(ntohs(hdr.type)) { - case 0x0800: pname = "IPv4"; break; - case 0x0806: pname = "ARP"; break; - default: pname = "unknown"; break; - }; - - dprintf("========== Ethernet Frame ==========\n"); - dprintf("Station: %02x:%02x:%02x:%02x:%02x:%02x ----> %02x:%02x:%02x:%02x:%02x:%02x\n", - hdr.src.byte[0], hdr.src.byte[1], hdr.src.byte[2], hdr.src.byte[3], hdr.src.byte[4], hdr.src.byte[5], - hdr.dst.byte[0], hdr.dst.byte[1], hdr.dst.byte[2], hdr.dst.byte[3], hdr.dst.byte[4], hdr.dst.byte[5]); - dprintf("Protocol: 0x%04x (%s)\n", ntohs(hdr.type), pname); -} - - -// ------------------- -static status_t init(net_layer *me) -{ - dprintf("%s: initing layer\n", me->name); - return B_OK; -} - -static status_t uninit(net_layer *me) -{ - dprintf("%s: uniniting layer\n", me->name); - return B_OK; -} - - -static status_t enable(net_layer *me, bool enable) -{ - return B_OK; -} - - -// ---------------------------------------------------- -static status_t process_input(net_layer *me, net_buffer *buffer) -{ - if (!buffer) - return B_ERROR; - - dprintf("%s: process_input:\n", me->name); - - dump_ethernet(buffer); - - g_stack->add_buffer_attribute(buffer, ethernet_header_attr, FROM_BUFFER, 0, 14); - g_stack->add_buffer_attribute(buffer, ethernet_to_attr, FROM_BUFFER, 0, 6); - g_stack->add_buffer_attribute(buffer, ethernet_from_attr, FROM_BUFFER, 6, 6); - g_stack->add_buffer_attribute(buffer, ethernet_protocol_attr, FROM_BUFFER | NETWORK_ORDER, 12, 2); - - // strip ethernet header - g_stack->remove_from_buffer(buffer, 0, 14); - - return g_stack->send_layers_up(me, buffer); -} - - -static status_t process_output(net_layer *me, net_buffer *buffer) -{ - if (!buffer) - return B_ERROR; - - // TODO! - dprintf("%s: process_output:\n", me->name); - return B_ERROR; -} - - -// #pragma mark - - -status_t std_ops(int32 op, ...) -{ - switch(op) { - case B_MODULE_INIT: { - status_t status; - - dprintf("ethernet_frame: B_MODULE_INIT\n"); - status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); - if (status != B_OK) - return status; - - ethernet_header_attr = g_stack->string_to_token("ethernet:header"); - ethernet_from_attr = g_stack->string_to_token("ethernet:from"); - ethernet_to_attr = g_stack->string_to_token("ethernet:to"); - ethernet_protocol_attr = g_stack->string_to_token("ethernet:protocol"); - - return g_stack->register_layer("Ethernet framing", "frame/ethernet", 0, &nlmi, NULL, NULL); - }; - - case B_MODULE_UNINIT: - dprintf("ethernet_frame: B_MODULE_UNINIT\n"); - put_module(NET_STACK_MODULE_NAME); - break; - - default: - return B_ERROR; - } - return B_OK; -} - -struct net_layer_module_info nlmi = { - { - NET_MODULES_ROOT "framings/ethernet_frame", - 0, - std_ops - }, - - NET_LAYER_API_VERSION, - - init, - uninit, - enable, - NULL, // no control() - process_input, - process_output -}; - -_EXPORT module_info *modules[] = { - (module_info*) &nlmi, // net_layer_module_info - NULL -}; diff --git a/src/tests/kits/net/new_stack/headers/memory_pool.h b/src/tests/kits/net/new_stack/headers/memory_pool.h deleted file mode 100644 index 57c9eff937..0000000000 --- a/src/tests/kits/net/new_stack/headers/memory_pool.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef OBOS_MEMORY_POOL_H -#define OBOS_MEMORY_POOL_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// Pools of *nodes* kernel module -// Pools store any node of data, but they should be all the same node_size -// size (set at pool creation time). -// Very usefull for multiple same-sized structs storage... - -struct memory_pool; -typedef struct memory_pool memory_pool; - -// for_each_pool_node() callback prototype: -typedef status_t (*pool_iterate_func)(memory_pool * pool, void * node, void * cookie); - -typedef struct { - module_info module; - - memory_pool * (*new_pool)(size_t node_size, uint32 node_count); - status_t (*delete_pool)(memory_pool * pool); - void * (*new_pool_node)(memory_pool * pool); - status_t (*delete_pool_node)(memory_pool * pool, void * node); - status_t (*for_each_pool_node)(memory_pool * pool, pool_iterate_func iterate, void * cookie); -} memory_pool_module_info; - -#define MEMORY_POOL_MODULE_NAME "generic/memory_pool/v1" - -#ifdef __cplusplus -} -#endif - -#endif /* OBOS_MEMORY_POOL_H */ - diff --git a/src/tests/kits/net/new_stack/headers/net_stack.h b/src/tests/kits/net/new_stack/headers/net_stack.h deleted file mode 100644 index 4c746766d4..0000000000 --- a/src/tests/kits/net/new_stack/headers/net_stack.h +++ /dev/null @@ -1,190 +0,0 @@ -/* net_stack.h - * definitions needed by all network stack modules - */ - -#ifndef OBOS_NET_STACK_H -#define OBOS_NET_STACK_H - -#include - -#include "memory_pool.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// String tokens use here and there by stack components -typedef const void *string_token; - -// Networking attribute(s) definition -typedef struct net_attribute net_attribute; - -#define NET_ATTRIBUTE_TYPE_MASK 0xFF // Up to 256 basic types -#define NET_ATTRIBUTE_FLAGS_MASK 0xFFFFFF00 -enum { - NET_ATTRIBUTE_BOOL = 1, // ... = bool value - NET_ATTRIBUTE_BYTE, // ... = uint8 value - NET_ATTRIBUTE_INT16, // ... = uint16 value - NET_ATTRIBUTE_INT32, // ... = uint32 value - NET_ATTRIBUTE_INT64, // ... = uint64 value - NET_ATTRIBUTE_DATA, // ... = void *data, size_t data_len - NET_ATTRIBUTE_STRING, // ... = char *string - NET_ATTRIBUTE_POINTER, // ... = void *ptr - NET_ATTRIBUTE_IOVEC // ... = int nb, iovec *vec -}; - -// Networking buffer(s) definition -typedef struct net_buffer net_buffer; -typedef struct net_buffer_queue net_buffer_queue; -typedef void (*buffer_chunk_free_func)(void * arg1, ...); // buffer chunk free callback prototype - -// Networking timers definitions -typedef struct net_timer net_timer; -typedef void (*net_timer_func)(net_timer *timer, void *cookie); // timer callback prototype - -// Generic lockers support -typedef int benaphore; -#define create_benaphore(a, b) -#define delete_benaphore(a) -#define lock_benaphore(a) -#define unlock_benaphore(a) - -// Networking layer(s) definitions -typedef struct net_layer net_layer; -typedef struct net_layer_module_info net_layer_module_info; - -#define NET_MODULES_ROOT "network_v2/" - -struct net_layer_module_info { - module_info info; - - uint32 api_version; - #define NET_LAYER_API_VERSION (0x1) - - status_t (*init)(net_layer *me); - status_t (*uninit)(net_layer *me); - status_t (*enable)(net_layer *me, bool enable); - status_t (*control)(net_layer *me, int opcode, ...); - status_t (*process_input)(net_layer *me, struct net_buffer *buffer); - status_t (*process_output)(net_layer *me, struct net_buffer *buffer); -}; - -struct net_layer { - struct net_layer *next; - char *name; - string_token type; // "frame", "ethernet" "ipv4", "ppp", etc. Joker (*) allowed - string_token sub_type; // joker (*) allowed here too. - int priority; // negative values reserved for packet sniffing, high value = lesser priority - net_layer_module_info *module; - void *cookie; - uint32 use_count; - struct net_layer **layers_above; - struct net_layer **layers_below; - net_attribute *attributes; // layer attributes -}; - -// Network stack main module definition - -struct net_stack_module_info { - module_info module; - - // Global stack control - status_t (*start)(void); - status_t (*stop)(void); - - // String IDs atomizer - string_token (*string_to_token)(const char *name); - const char * (*string_for_token)(string_token token); - - /* - * Socket layer - */ - - /* - * Net layers handling - */ - - status_t (*register_layer)(const char *name, const char *packets_type, int priority, - net_layer_module_info *module, void *cookie, net_layer **layer); - status_t (*unregister_layer)(net_layer *layer); - net_layer * (*find_layer)(const char *name); - - status_t (*add_layer_attribute)(net_layer *layer, string_token id, int type, ...); - status_t (*remove_layer_attribute)(net_layer *layer, string_token id, int index); - status_t (*find_layer_attribute)(net_layer *layer, string_token id, int index, - int *type, void **value, size_t *size); - - status_t (*send_layers_up)(net_layer *me, net_buffer *buffer); - status_t (*send_layers_down)(net_layer *me, net_buffer *buffer); - - /* - * Buffer(s) support - */ - - - net_buffer * (*new_buffer)(void); - status_t (*delete_buffer)(net_buffer *buffer, bool interrupt_safe); - - net_buffer * (*duplicate_buffer)(net_buffer *from); - net_buffer * (*clone_buffer)(net_buffer *from); - net_buffer * (*split_buffer)(net_buffer *from, uint32 offset); - - - // specials offsets for add_to_buffer() - #define BUFFER_BEGIN 0 - #define BUFFER_END 0xFFFFFFFF - status_t (*add_to_buffer)(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis); - status_t (*remove_from_buffer)(net_buffer *buffer, uint32 offset, size_t bytes); - - status_t (*attach_buffer_free_element)(net_buffer *buffer, void *arg1, void *arg2, buffer_chunk_free_func freethis); - - size_t (*read_buffer)(net_buffer *buffer, uint32 offset, void *data, size_t bytes); - size_t (*write_buffer)(net_buffer *buffer, uint32 offset, const void *data, size_t bytes); - - // Flags to combine with - #define FROM_BUFFER 0x010000 // ... = int offset, int size - #define NETWORK_ORDER 0x020000 - status_t (*add_buffer_attribute)(net_buffer *buffer, string_token id, int type, ...); - status_t (*remove_buffer_attribute)(net_buffer *buffer, string_token id, int index); - status_t (*find_buffer_attribute)(net_buffer *buffer, string_token id, int index, - int *type, void **value, size_t *size); - - void (*dump_buffer)(net_buffer *buffer); - - // Buffers queues support - net_buffer_queue * (*new_buffer_queue)(size_t max_bytes); - status_t (*delete_buffer_queue)(net_buffer_queue *queue); - - status_t (*empty_buffer_queue)(net_buffer_queue *queue); - status_t (*enqueue_buffer)(net_buffer_queue *queue, net_buffer *buffer); - size_t (*dequeue_buffer)(net_buffer_queue *queue, net_buffer **buffer, bigtime_t timeout, bool peek); - - // Timers support - - net_timer * (*new_timer)(void); - status_t (*delete_timer)(net_timer *timer); - status_t (*start_timer)(net_timer *timer, net_timer_func func, void *cookie, bigtime_t period); - status_t (*cancel_timer)(net_timer *timer); - status_t (*timer_appointment)(net_timer *timer, bigtime_t *period, bigtime_t *when); - - // Lockers - - // Misc. - void (*dump_memory)(const char *prefix, const void *data, size_t len); - - // Memory Pools support - memory_pool * (*new_pool)(size_t node_size, uint32 node_count); - status_t (*delete_pool)(memory_pool *pool); - void * (*new_pool_node)(memory_pool *pool); - status_t (*delete_pool_node)(memory_pool *pool, void *node); - status_t (*for_each_pool_node)(memory_pool *pool, pool_iterate_func iterate, void *cookie); - -}; - -#define NET_STACK_MODULE_NAME NET_MODULES_ROOT "stack/v1" - -#ifdef __cplusplus -} -#endif - -#endif /* OBOS_NET_STACK_H */ diff --git a/src/tests/kits/net/new_stack/interfaces/Jamfile b/src/tests/kits/net/new_stack/interfaces/Jamfile deleted file mode 100644 index 5e78f47524..0000000000 --- a/src/tests/kits/net/new_stack/interfaces/Jamfile +++ /dev/null @@ -1,5 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack interfaces ; - -SubInclude HAIKU_TOP src tests kits net new_stack interfaces ether_drivers ; -SubInclude HAIKU_TOP src tests kits net new_stack interfaces loopback ; -# SubInclude HAIKU_TOP src tests kits net new_stack interfaces dialup ; diff --git a/src/tests/kits/net/new_stack/interfaces/ether_drivers/Jamfile b/src/tests/kits/net/new_stack/interfaces/ether_drivers/Jamfile deleted file mode 100644 index e3b4042422..0000000000 --- a/src/tests/kits/net/new_stack/interfaces/ether_drivers/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack interfaces ether_drivers ; - -UseHeaders [ FDirName $(HAIKU_TOP) src tests kits net new_stack headers ] ; - -Addon ether_drivers : - ether_drivers.c - : new_stack_tester be -; diff --git a/src/tests/kits/net/new_stack/interfaces/ether_drivers/ether_drivers.c b/src/tests/kits/net/new_stack/interfaces/ether_drivers/ether_drivers.c deleted file mode 100644 index 5f32c332aa..0000000000 --- a/src/tests/kits/net/new_stack/interfaces/ether_drivers/ether_drivers.c +++ /dev/null @@ -1,356 +0,0 @@ -/* legacy_devices.c - generic ethernet legacy devices layer module - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "net_stack.h" - -enum { - ETHER_GETADDR = B_DEVICE_OP_CODES_END, - ETHER_INIT, - ETHER_NONBLOCK, - ETHER_ADDMULTI, - ETHER_REMMULTI, - ETHER_SETPROMISC, - ETHER_GETFRAMESIZE -}; - -typedef struct ether_drivers_device { - int fd; - int max_frame_size; - volatile thread_id reader_thread; -} ether_drivers_device; - -#define ETHER_ADDR_LEN 6 /* Ethernet address length */ -#define ETHER_TYPE_LEN 2 /* Ethernet type field length */ -#define ETHER_CRC_LEN 4 /* Ethernet CRC lenght */ -#define ETHER_HDR_LEN ((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN) -#define ETHER_MIN_LEN 64 /* Minimum frame length, CRC included */ -#define ETHER_MAX_LEN 1518 /* Maximum frame length, CRC included */ - -#define ETHERMTU (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) -#define ETHERMIN (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) - -typedef struct ethernet_addr { - uint8 byte[ETHER_ADDR_LEN]; -} ethernet_addr; - -status_t lookup_devices(char *root, void *cookie); -status_t register_device(const char *path, void *cookie); -status_t device_reader(void *args); -status_t std_ops(int32 op, ...); - -struct net_layer_module_info nlmi; - -static struct net_stack_module_info *g_stack = NULL; - - -// ------------------- -static status_t init(net_layer *me) -{ - dprintf("%s: initing layer\n", me->name); - return B_OK; -} - -static status_t uninit(net_layer *me) -{ - ether_drivers_device *edd = me->cookie; - - dprintf("%s: uniniting layer\n", me->name); - - close(edd->fd); - free(me->cookie); - - return B_OK; -} - - -static status_t enable(net_layer *me, bool enable) -{ - ether_drivers_device *edd = me->cookie; - - if (enable) { - // enable this layer - thread_id tid; - char name[B_OS_NAME_LENGTH * 2]; - - if (edd->reader_thread != -1) - // already up - return B_OK; - - strncpy(name, me->name, sizeof(name)); - strncat(name, " reader", sizeof(name)); - tid = spawn_kernel_thread(device_reader, name, B_NORMAL_PRIORITY, me); - if (tid < 0) { - dprintf("%s: failed to start device reader thread -> %d [%s]\n", - me->name, (int) tid, strerror(tid)); - return tid; - }; - - edd->reader_thread = tid; - return resume_thread(tid); - - } else { - - status_t dummy; - - // disable this layer - if (edd->reader_thread == -1) - // already down - return B_OK; - - send_signal_etc(edd->reader_thread, SIGTERM, 0); - wait_for_thread(edd->reader_thread, &dummy); - dprintf("%s: device reader stopped.\n", me->name); - edd->reader_thread = -1; - return B_OK; - }; - - return B_OK; -} - - -static status_t process_output(net_layer *me, net_buffer *buffer) -{ - ether_drivers_device *edd = me->cookie; - status_t status; - void *frame; - ssize_t sz; - - if (!buffer) - return B_ERROR; - - dprintf("%s: process_output:\n", me->name); - g_stack->dump_buffer(buffer); - - // write buffer content - frame = malloc(edd->max_frame_size); - if (!frame) - return B_NO_MEMORY; - - // TODO: remove unwanted copy!!! - sz = g_stack->read_buffer(buffer, 0, frame, edd->max_frame_size); - if (sz >= 1) - sz = write(edd->fd, frame, sz); - - g_stack->delete_buffer(buffer, false); - return (sz >= 0); -} - - -// #pragma mark - - -status_t lookup_devices(char *root, void *cookie) -{ - DIR *dir; - struct dirent *de; - struct stat st; - char path[1024]; - status_t status; - - dir = opendir(root); - if (!dir) { - dprintf("Couldn't open the directory %s\n", root); - return B_ERROR; - }; - - status = B_OK; - - while ((de = readdir(dir)) != NULL) { - if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) - continue; // skip pseudo-directories - - sprintf(path, "%s/%s", root, de->d_name); - - if (stat(path, &st) < 0) { - dprintf("ether_drivers: Can't stat(%s) entry! Skipping...\n", path); - continue; - }; - - if (S_ISDIR(st.st_mode)) - status = lookup_devices(path, cookie); - else if (S_ISCHR(st.st_mode)) { // char device = driver! - if (strcmp(de->d_name, "socket") == 0 || // Old OBOS stack driver - strcmp(de->d_name, "stack") == 0 || // OBOS stack driver - strcmp(de->d_name, "server") == 0 || // OBOS server driver - strcmp(de->d_name, "api") == 0) // BONE stack driver - continue; // skip pseudo-entries - - status = register_device(path, cookie); - }; - }; - - closedir(dir); - - return status; -} - - -status_t register_device(const char *path, void *cookie) -{ - ether_drivers_device *edd; - int frame_size; - ethernet_addr mac_address; - int fd; - status_t status; - - fd = open(path, O_RDWR); - if (fd < B_OK) { - dprintf("ether_drivers: Unable to open %s device -> %d [%s]. Skipping...\n", path, - fd, strerror(fd)); - return fd; - }; - - // Init the network card - status = ioctl(fd, ETHER_INIT, NULL, 0); - if (status < B_OK) { - dprintf("ether_drivers: Failed to init %s device -> %ld [%s]. Skipping...\n", path, - status, strerror(status)); - close(fd); - return status; - }; - - // get the MAC address... - status = ioctl(fd, ETHER_GETADDR, &mac_address, 6); - if (status < B_OK) { - dprintf("ether_drivers: Failed to get %s device MAC address -> %ld [%s]. Skipping...\n", - path, status, strerror(status)); - close(fd); - return status; - }; - - // Try to determine the MTU to use - status = ioctl(fd, ETHER_GETFRAMESIZE, &frame_size, sizeof(frame_size)); - if (status < B_OK) { - frame_size = ETHERMTU; - dprintf("ether_drivers: %s device don't support ETHER_GETFRAMESIZE; defaulting to %d\n", - path, frame_size); - }; - - dprintf("ether_drivers: Found device '%s': MAC address: %02x:%02x:%02x:%02x:%02x:%02x, MTU: %d bytes\n", - path, - mac_address.byte[0], mac_address.byte[1], - mac_address.byte[2], mac_address.byte[3], - mac_address.byte[4], mac_address.byte[5], frame_size); - - edd = malloc(sizeof(*edd)); - if (!edd) { - close(fd); - return B_NO_MEMORY; - }; - - edd->fd = fd; - edd->max_frame_size = frame_size; - edd->reader_thread = -1; - - if (strncmp(path, "/dev/net/", 9) == 0) - path += 9; // drop the path root from layer(s) name(s) - - return g_stack->register_layer(path, "interface/ethernet", 0, &nlmi, edd, NULL); -} - -// ---------------------------------------------------- -status_t device_reader(void *args) -{ - net_layer *me = args; - ether_drivers_device *edd = me->cookie; - net_buffer *buffer; - status_t status; - void *frame; - ssize_t sz; - - dprintf("%s: device reader started.\n", me->name); - - status = B_OK; - while(1) { - frame = malloc(edd->max_frame_size); - if (!frame) { - status = B_NO_MEMORY; - break; - }; - - // read on frame at time - sz = read(edd->fd, frame, edd->max_frame_size); - if (sz >= B_OK) { - buffer = g_stack->new_buffer(); - if (!buffer) { - free(frame); - status = B_NO_MEMORY; - break; - }; - - g_stack->add_to_buffer(buffer, 0, frame, sz, (buffer_chunk_free_func) free); - - dprintf("%s: input packet %p:\n", me->name, buffer); - if (g_stack->send_layers_up(me, buffer) != B_OK) { - // nobody above us *eat* this packet, so we drop it ourself :-( - dprintf("%s: okay, nobody cares about this input packet %p: deletion!\n", me->name, buffer); - g_stack->dump_buffer(buffer); - g_stack->delete_buffer(buffer, false); - }; - }; - }; - - edd->reader_thread = -1; - return status; -} - -// #pragma mark - - -status_t std_ops(int32 op, ...) -{ - switch(op) { - case B_MODULE_INIT: { - status_t status; - - dprintf("ether_drivers: B_MODULE_INIT\n"); - status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); - if (status != B_OK) - return status; - - lookup_devices("/dev/net", NULL); - return B_OK; - }; - - case B_MODULE_UNINIT: - dprintf("ether_drivers: B_MODULE_UNINIT\n"); - put_module(NET_STACK_MODULE_NAME); - break; - - default: - return B_ERROR; - } - return B_OK; -} - -struct net_layer_module_info nlmi = { - { - NET_MODULES_ROOT "interfaces/ether_drivers", - 0, - std_ops - }, - - NET_LAYER_API_VERSION, - - init, - uninit, - enable, - NULL, // no control() - NULL, // interface layer: processing input buffer doesn't make sense! - process_output -}; - -_EXPORT module_info *modules[] = { - (module_info*) &nlmi, // net_layer_module_info - NULL -}; diff --git a/src/tests/kits/net/new_stack/interfaces/loopback/Jamfile b/src/tests/kits/net/new_stack/interfaces/loopback/Jamfile deleted file mode 100644 index 413d65f199..0000000000 --- a/src/tests/kits/net/new_stack/interfaces/loopback/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack interfaces loopback ; - -UseHeaders [ FDirName $(HAIKU_TOP) src tests kits net new_stack headers ] ; - -Addon loopback : - loopback.c - : new_stack_tester be -; diff --git a/src/tests/kits/net/new_stack/interfaces/loopback/loopback.c b/src/tests/kits/net/new_stack/interfaces/loopback/loopback.c deleted file mode 100644 index 42aa7e1a07..0000000000 --- a/src/tests/kits/net/new_stack/interfaces/loopback/loopback.c +++ /dev/null @@ -1,96 +0,0 @@ -/* loopback.c - loopback interface module - */ - -#include -#include -#include -#include - -#include - -#include "net_stack.h" - -status_t std_ops(int32 op, ...); - -struct net_layer_module_info nlmi; - -static struct net_stack_module_info *g_stack = NULL; - - -// ------------------- -static status_t init(net_layer *me) -{ - dprintf("%s: initing layer\n", me->name); - return B_OK; -} - -static status_t uninit(net_layer *me) -{ - dprintf("loopback: uniniting layer\n"); - return B_OK; -} - - -static status_t enable(net_layer *me, bool enable) -{ - return B_OK; -} - - -static status_t process_output(net_layer *me, net_buffer *buffer) -{ - if (!buffer) - return B_ERROR; - - // Here the magical loopback effect ;-) - return g_stack->send_layers_up(me, buffer); -} - -// #pragma mark - - -status_t std_ops(int32 op, ...) -{ - switch(op) { - case B_MODULE_INIT: { - status_t status; - - dprintf("loopback: B_MODULE_INIT\n"); - status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); - if (status != B_OK) - return status; - - return g_stack->register_layer("loopback", "interface/*", 0, &nlmi, NULL, NULL); - } - - case B_MODULE_UNINIT: - dprintf("loopback: B_MODULE_UNINIT\n"); - put_module(NET_STACK_MODULE_NAME); - break; - - default: - return B_ERROR; - } - return B_OK; -} - -struct net_layer_module_info nlmi = { - { - NET_MODULES_ROOT "interfaces/loopback", - 0, - std_ops - }, - - NET_LAYER_API_VERSION, - - init, - uninit, - enable, - NULL, // no control() - NULL, // interface layer: processing input buffer doesn't make sense! - process_output -}; - -_EXPORT module_info *modules[] = { - (module_info*) &nlmi, // net_layer_module_info - NULL -}; diff --git a/src/tests/kits/net/new_stack/memory_pool/Jamfile b/src/tests/kits/net/new_stack/memory_pool/Jamfile deleted file mode 100644 index c621026e51..0000000000 --- a/src/tests/kits/net/new_stack/memory_pool/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack memory_pool ; - -UseHeaders [ FDirName $(HAIKU_TOP) src tests kits net new_stack headers ] ; - -Addon memory_pool : - memory_pool.c - : new_stack_tester -; diff --git a/src/tests/kits/net/new_stack/memory_pool/memory_pool.c b/src/tests/kits/net/new_stack/memory_pool/memory_pool.c deleted file mode 100644 index 82f2f370d4..0000000000 --- a/src/tests/kits/net/new_stack/memory_pool/memory_pool.c +++ /dev/null @@ -1,295 +0,0 @@ -#include // for the hack using malloc() / free() -#include -#include - -#include "memory_pool.h" - -// Keep in mind that pools size are rounded to B_PAGE_SIZE, and -// node_size are align to 32 bits boundaries... - -struct memory_pool { - struct memory_pool * next; // for dynamic pool expansion/shrinking... - size_t node_size; // in byte, rounded to 32 bits boundary - uint32 node_count; - // struct memory_pool_block blocks[1]; -}; - -typedef struct memory_pool_block { - uint32 nb_max; // in this pool only, may vary from pool to another for same pools chain - uint32 nb_free; // in this pool only, if 0 try 'next' one... - void * first; // address of first node, just next to freemap - void * last; // address of last node in this pool - // the uint32 freemap[] follow, aligned to 32 bits boundary - // then the nodes data follow... -} memory_pool_block; - -#define BITMAPSIZE(nb_nodes) (nb_nodes / 8) - -status_t std_ops(int32 op, ...); - -memory_pool * new_pool(size_t node_size, uint32 node_count); -status_t delete_pool(memory_pool * pool); -void * new_pool_node(memory_pool * pool); -status_t delete_pool_node(memory_pool * pool, void * node); -status_t for_each_pool_node(memory_pool * pool, pool_iterate_func iterate, void * cookie); - -// Keep in mind that pools size are rounded to B_PAGE_SIZE... - -#define ROUND(x, y) (((x) + (y) - 1) & ~((y) - 1)) - -#define DEBUG 1 - - - -#ifdef CODEWARRIOR - #pragma mark [Public functions] -#endif - -// ------------------------------- -memory_pool * new_pool(size_t node_size, uint32 node_count) -{ - // TODO! - return (memory_pool *) node_size; // quick hack -} - - -// ------------------------------- -status_t delete_pool(memory_pool * pool) -{ - // TODO! - - return 0; // return B_OK; -} - - -// ------------------------------- -void * new_pool_node(memory_pool * pool) -{ - // TODO! - - return malloc((size_t) pool); // quick hack -} - - -// ------------------------------- -status_t delete_pool_node(memory_pool * pool, void * node) -{ - // TODO! - - free(node); // quick hack - return 0; // return B_OK; -} - - -// ------------------------------- -status_t for_each_pool_node(memory_pool * pool, pool_iterate_func iterate, void * cookie) -{ - // TODO! - return 0; // return B_OK; -} - - -#if 0 - -// ------------------------------- -memory_pool * new_pool2(size_t node_size, uint32 node_count) -{ - memory_pool * pool; - size_t size; - size_t freemap_size; - uint8 * ptr; - - - node_size = ROUND(node_size, 4); // aligned to 32 bits - - freemap_size = ROUND(node_count, 32) / 8; // aligned to 32 bits - - size = sizeof(memory_pool); - - size += freemap_size; - size += node_size * node_count; - - pool = (memory_pool *) malloc(size); - - pool->next = NULL; // no secondary pool for the moment... - - pool->node_size = node_size; // aligned to 32 bits - pool->nb_max = node_count; - pool->nb_free = node_count; - - ptr = (uint8 *) (pool + 1); - ptr += freemap_size; - - pool->first = ptr; - - ptr += (node_count-1) * node_size; - - pool->last = ptr; - - return pool; -} - - - -// ------------------------------- -status_t delete_pool2(memory_pool * pool) -{ - memory_pool * next; - - while (pool) { - next = pool->next; - - my_free2("delete_pool: ", pool); - - pool = next; - }; - - return 0; // return B_OK; -} - - -// ------------------------------- -void * new_pool_node2(memory_pool * pool) -{ - memory_pool * p; - size_t slot; - sizet nb_slots; - uint32* freemap; - uint8 * ptr; - - // seaching pools list for one with at least one free node - p = pool; - while (p->nb_free == 0) { - p = p->next; - }; - - if (! p) { - // need to add a new pool - p = new_pool2(pool->node_size, pool->nb_max); - if (!p) - return NULL; // argh, no more memory!?! - - p->next = pool->next; - pool->next = p; - }; - - // okay, now find the first free slot of this pool - slot = 0; - nb_slots = ROUND(p->nb_max, 32); // aligned to 32 bits - freemap = (uint32 *) (p + 1); - - // fast lookup over 32 contiguous slots already in use (if any) - while (slot < nb_slots) { - if (*freemap != 0xFFFFFFFF) - break; - - freemap++; // all 32 contiguous slots used - slot += 32; - }; - - // find the first free slot of these next 32 ones - while(slot < nb_slots) { - if ( *freemap & (1 << (31 - (slot % 32))) == 0) - // free slot found :-) - break; - - slot++; - }; - - if (slot >= nb_slots) - // oh oh, should never happend! ;-) - return NULL; - - *freemap |= (1 << (31 - (slot % 32))); - p->nb_free--; - - ptr = (uint8 *) p->first; - ptr += slot * p->node_size; - - return ptr; -} - - -// ------------------------------- -status_t delete_pool_node2(memory_pool * pool, void * node) -{ - memory_pool * p; - size_t slot; - size_t nb_slots; - uint32* freemap; - uint8 * ptr; - - // seaching pools list for the one who host this node - p = pool; - while (pool) { - if (node >= pool->first && node <= pool->last) - break; // node's hosting pool found - pool = pool->next; - }; - - if (! pool) - return -1; // return B_BAD_VALUE; - - // find node slot number on this pool - slot = (node - pool->first); - if (slot % pool->node_size) - // oh oh, not a valid, starting node address value! - return -1; // return B_BAD_VALUE; - - nb_slots = ROUND(p->nb_max, 32); // aligned to 32 bits - slot /= pool->node_size; - if (slot >= nb_slots) - // oh oh, node slot out of range!!! - // something go wrong with pool->last value!?! - return -1; // return B_BAD_VALUE; - - freemap = (uint32 *) (pool + 1); - - pool->nb_free++; - if (pool->nb_free == pool->nb_max) - // free this pool_block - - return 0; // return B_OK; -} - -#endif - -// #pragma mark - - -memory_pool_module_info mpmi = { - { - MEMORY_POOL_MODULE_NAME, - 0, - std_ops - }, - - new_pool, - delete_pool, - new_pool_node, - delete_pool_node, - for_each_pool_node -}; - -status_t std_ops(int32 op, ...) -{ - switch(op) { - case B_MODULE_INIT: - printf("memory_pool: B_MODULE_INIT\n"); - break; - - case B_MODULE_UNINIT: - printf("memory_pool: B_MODULE_UNINIT\n"); - break; - - default: - return B_ERROR; - } - return B_OK; -} - - -_EXPORT module_info *modules[] = { - (module_info *) &mpmi, // memory_pool_module_info - NULL -}; - diff --git a/src/tests/kits/net/new_stack/net_stack_server.cpp b/src/tests/kits/net/new_stack/net_stack_server.cpp deleted file mode 100644 index 008423a9b1..0000000000 --- a/src/tests/kits/net/new_stack/net_stack_server.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* Userland modules emulation support -*/ - -#include -#include -#include - -#include -#include - -#include "net_stack.h" -// #include - -struct net_stack_module_info * g_stack = NULL; - -void my_free(void * ptr, ...) -{ - printf("my_free(%p)\n", ptr); - free(ptr); -} - -void my_free2(void * prompt, ...) // void * ptr) -{ - va_list args; - void * ptr; - - va_start(args, prompt); - ptr = va_arg(args, void *); - va_end(args); - - printf("%s: my_free2(%p)\n", (char *) prompt, ptr); - free(ptr); -} - -int test_buffer() -{ - net_buffer *buffer; - char data[128]; - size_t len; - char *tata; - char *titi; - char *toto; - char *tutu; - - puts("test_buffer():"); - - tata = (char *) malloc(16); - strcpy(tata, "0123456789"); - - titi = (char *) malloc(16); - strcpy(titi, "ABCDEF"); - - toto = (char *) malloc(48); - strcpy(toto, "abcdefghijklmnopqrstuvwxyz"); - - tutu = (char *) malloc(16); - strcpy(tutu, "hello there!"); - - buffer = g_stack->new_buffer(); - - g_stack->add_to_buffer(buffer, BUFFER_END, titi, 6, my_free); - g_stack->add_to_buffer(buffer, 0, tata, 10, my_free); - g_stack->attach_buffer_free_element(buffer, tutu, (void *) "hello there", my_free2); - g_stack->add_to_buffer(buffer, 5, toto, 26, my_free); - g_stack->add_to_buffer(buffer, 0, "this is a net_buffer test: ", 27, NULL); - - g_stack->dump_buffer(buffer); - - printf("Removing 61 bytes at offset 4...\n"); - g_stack->remove_from_buffer(buffer, 4, 61); - - g_stack->dump_buffer(buffer); - - len = g_stack->read_buffer(buffer, 2, data, sizeof(data)); - data[len] = 0; - - printf("data = [%s]\n", data); - - g_stack->delete_buffer(buffer, false); - return 0; -} - - -int main(int argc, char **argv) -{ - int ret = -1; - - new BApplication("application/x-vnd-OBOS-net_server"); - - // if (init_userland_ipc() < B_OK) - // goto exit0; - - if (get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack) != B_OK) - goto exit1; - - if (g_stack->start() == B_OK) { - - puts("Userland net stack (net_server) is running."); - puts("Press any key to quit."); - - fflush(stdin); - fgetc(stdin);; - - // test_buffer(); - - g_stack->stop(); - }; - - put_module(NET_STACK_MODULE_NAME);; - - ret = 0; - - exit1:; - // shutdown_userland_ipc(); - -// exit0:; - delete be_app; - return ret; -} - diff --git a/src/tests/kits/net/new_stack/protocols/Jamfile b/src/tests/kits/net/new_stack/protocols/Jamfile deleted file mode 100644 index 2adeac1418..0000000000 --- a/src/tests/kits/net/new_stack/protocols/Jamfile +++ /dev/null @@ -1,5 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack protocols ; - -SubInclude HAIKU_TOP src tests kits net new_stack protocols arp ; -SubInclude HAIKU_TOP src tests kits net new_stack protocols ipv4 ; - diff --git a/src/tests/kits/net/new_stack/protocols/arp/Jamfile b/src/tests/kits/net/new_stack/protocols/arp/Jamfile deleted file mode 100644 index 52a43bfa6f..0000000000 --- a/src/tests/kits/net/new_stack/protocols/arp/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack protocols arp ; - -UseHeaders [ FDirName $(HAIKU_TOP) src tests kits net new_stack headers ] ; - -Addon arp : - arp.c - : new_stack_tester be -; diff --git a/src/tests/kits/net/new_stack/protocols/arp/arp.c b/src/tests/kits/net/new_stack/protocols/arp/arp.c deleted file mode 100644 index 1005fc1774..0000000000 --- a/src/tests/kits/net/new_stack/protocols/arp/arp.c +++ /dev/null @@ -1,219 +0,0 @@ -/* ethernet.c - ethernet devices interface module - */ - -#include -#include -#include - -#include -#include - -#include "net_stack.h" - -status_t std_ops(int32 op, ...); - -struct net_layer_module_info nlmi; - -static struct net_stack_module_info *g_stack = NULL; - -string_token ethernet_protocol_attr; - -typedef struct ethernet_addr { - uint8 byte[6]; -} ethernet_addr; - -typedef struct ipv4_addr { - uint8 byte[4]; -} ipv4_addr; - -struct arp_header { - uint16 hardware_type; /* format of hardware address */ - uint16 protocol_type; /* format of protocol address */ - uint8 hardware_size; /* length of hardware address */ - uint8 protocol_size; /* length of protocol address */ - uint16 op; /* one of: */ - - // for ethernet/ipv4 arp packets - - ethernet_addr sender_hardware_address; /* sender hardware address */ - ipv4_addr sender_protocol_address; /* sender protocol address */ - ethernet_addr target_hardware_address; /* target hardware address */ - ipv4_addr target_protocol_address; /* target protocol address */ -}; - -enum { - ARP_HARDWARE_TYPE_ETHERNET = 1, /* ethernet hardware format */ - ARP_HARDWARE_TYPE_IEEE802 = 6, /* IEEE 802 hardware format */ - ARP_HARDWARE_TYPE_FRAMERELAY = 15 -}; - -enum { - ARP_OP_REQUEST = 1, /* request to resolve address */ - ARP_OP_REPLY, - ARP_OP_RARP_REQUEST, - ARP_OP_RARP_REPLY -}; - -static void dump_arp(net_buffer *buffer) -{ - struct arp_header arp; - const char *pname; - ethernet_addr *ea; - ipv4_addr *ia; - - g_stack->read_buffer(buffer, 0, &arp, sizeof(arp)); - - switch(ntohs(arp.protocol_type)) { - case 0x0800: pname = "IPv4"; break; - case 0x0806: pname = "ARP"; break; - default: pname = "unknown"; break; - }; - - dprintf("========== Address Resolution Protocol (ARP) ====\n"); - dprintf("Hardware : %s\n", - ntohs(arp.hardware_type) == ARP_HARDWARE_TYPE_ETHERNET ? "ethernet" : "unknown"); - dprintf("Protocol : 0x%04x (%s)\n", ntohs(arp.protocol_type), pname); - dprintf("Operation : "); - switch(ntohs(arp.op)) { - case ARP_OP_REPLY: - dprintf("ARP Reply\n"); - break; - case ARP_OP_REQUEST: - dprintf("ARP Request\n"); - break; - default: - dprintf("Who knows? 0x%04x\n", ntohs(arp.op)); - }; - dprintf("Hardware address length: %d\n", arp.hardware_size); - dprintf("Protocol address length: %d\n", arp.protocol_size); - - ea = &arp.sender_hardware_address; - dprintf("Sender Hardware Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - ea->byte[0], ea->byte[1], ea->byte[2], ea->byte[3], ea->byte[4], ea->byte[5]); - ia = &arp.sender_protocol_address; - dprintf("Sender Protocol Address: %d.%d.%d.%d\n", - ia->byte[0], ia->byte[1], ia->byte[2], ia->byte[3]); - - ea = &arp.target_hardware_address; - dprintf("Target Hardware Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - ea->byte[0], ea->byte[1], ea->byte[2], ea->byte[3], ea->byte[4], ea->byte[5]); - ia = &arp.target_protocol_address; - dprintf("Target Protocol Address: %d.%d.%d.%d\n", - ia->byte[0], ia->byte[1], ia->byte[2], ia->byte[3]); -} - - -// #pragma mark - - - -// ------------------- -static status_t init(net_layer *me) -{ - dprintf("%s: initing layer\n", me->name); - return B_OK; - -} - -static status_t uninit(net_layer *me) -{ - dprintf("%s: uniniting layer\n", me->name); - return B_OK; -} - - -static status_t enable(net_layer *me, bool enable) -{ - return B_OK; -} - - -static status_t process_input(net_layer *me, net_buffer *buffer) -{ - uint16 *protocol; - - if (!buffer) - return B_ERROR; - - if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, 0, NULL, (void **) &protocol, NULL) != B_OK) - return B_ERROR; - - if (*protocol != htons(0x0806)) // ARP on Ethernet protocol value - // Not an ARP packet - return B_ERROR; - - // TODO! - dump_arp(buffer); - g_stack->delete_buffer(buffer, false); - - return B_OK; -} - -static status_t process_output(net_layer *me, net_buffer *buffer) -{ - if (!buffer) - return B_ERROR; - - // TODO! - return B_OK; -} - -// #pragma mark - - -status_t std_ops(int32 op, ...) -{ - switch(op) { - case B_MODULE_INIT: { - status_t status; - net_layer *layer; - - dprintf("arp: B_MODULE_INIT\n"); - status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); - if (status != B_OK) - return status; - - ethernet_protocol_attr = g_stack->string_to_token("ethernet:protocol"); - - status = g_stack->register_layer("ARP", "ethernet/arp", 30, &nlmi, NULL, &layer); - if (status != B_OK) - goto error; - - return B_OK; - -error: - g_stack->unregister_layer(layer); - put_module(NET_STACK_MODULE_NAME); - return status; - } - - case B_MODULE_UNINIT: - dprintf("arp: B_MODULE_UNINIT\n"); - put_module(NET_STACK_MODULE_NAME); - break; - - default: - return B_ERROR; - } - return B_OK; -} - -struct net_layer_module_info nlmi = { - { - NET_MODULES_ROOT "protocols/arp/v0", - 0, - std_ops - }, - - NET_LAYER_API_VERSION, - - init, - uninit, - enable, - NULL, - process_input, - process_output -}; - -_EXPORT module_info *modules[] = { - (module_info*) &nlmi, // net_layer_module_info - NULL -}; diff --git a/src/tests/kits/net/new_stack/protocols/ipv4/Jamfile b/src/tests/kits/net/new_stack/protocols/ipv4/Jamfile deleted file mode 100644 index f780a58830..0000000000 --- a/src/tests/kits/net/new_stack/protocols/ipv4/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack protocols ipv4 ; - -UseHeaders [ FDirName $(HAIKU_TOP) src tests kits net new_stack headers ] ; - -Addon ipv4 : - ipv4.c - : new_stack_tester be -; diff --git a/src/tests/kits/net/new_stack/protocols/ipv4/ipv4.c b/src/tests/kits/net/new_stack/protocols/ipv4/ipv4.c deleted file mode 100644 index 897cfa1275..0000000000 --- a/src/tests/kits/net/new_stack/protocols/ipv4/ipv4.c +++ /dev/null @@ -1,203 +0,0 @@ -/* ipv4.c - ipv4 protocol module - */ - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "net_stack.h" - -typedef uint32 ipv4_addr; - -typedef struct ipv4_header { - uint8 version_header_length; - uint8 tos; - uint16 total_length; - uint16 identification; - uint16 flags_frag_offset; - uint8 ttl; - uint8 protocol; - uint16 header_checksum; - ipv4_addr src; - ipv4_addr dst; -} _PACKED ipv4_header; - -#define IPV4_FLAG_MORE_FRAGS 0x2000 -#define IPV4_FLAG_MAY_NOT_FRAG 0x4000 -#define IPV4_FRAG_OFFSET_MASK 0x1fff - - - -status_t std_ops(int32 op, ...); - -struct net_layer_module_info nlmi; - -static struct net_stack_module_info *g_stack = NULL; -string_token ethernet_protocol_attr; -static uint32 g_next_ipv4_id = 0; - -static void dump_ipv4_addr(ipv4_addr *addr) -{ - uint8 *bytes = (uint8 *) addr; - - // NOTE: addr should point to a Network Byte Order'ed (aka Big Endian) IPv4 address - - dprintf("%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); -} - -static void dump_ipv4_header(net_buffer *buffer) -{ - ipv4_header ip; - const char *pname; - - g_stack->read_buffer(buffer, 0, &ip, sizeof(ip)); - - switch(ip.protocol) { - case 1: pname = "ICMP"; break; - case 6: pname = "TCP"; break; - case 17: pname = "UDP"; break; - default: pname = "unknown"; break; - }; - - dprintf("========== Internet Protocol (IPv4) =============\n"); - - dprintf("Station: "); - dump_ipv4_addr(&ip.src); - dprintf(" ----> "); - dump_ipv4_addr(&ip.dst); - dprintf("\n"); - dprintf("Protocol: %d (%s)\n", ip.protocol, pname); - dprintf("Version: %d\n", ip.version_header_length >> 4); - dprintf("Header Length (32 bit words): %d (%d bytes)\n", - ip.version_header_length & 0x0f, - 4 * (ip.version_header_length & 0x0f)); - // TODO: dprintf("Precedence: \n"); - dprintf("Total length: %d\n", ntohs(ip.total_length)); - dprintf("Identification: %d\n", ntohs(ip.identification)); - // TODO: dprintf("Fragmentation allowed, Last fragment\n"); - dprintf("Fragment Offset: %d\n", ntohs(ip.flags_frag_offset) & 0x1fff); - dprintf("Time to Live: %d second(s)\n", ip.ttl); - dprintf("Checksum: 0x%X (%s)\n", ntohs(ip.header_checksum), "Valid"); // TODO: check the checksum! -} - -// #pragma mark - - - -// ------------------- -static status_t init(net_layer *me) -{ - printf("%s: initing layer\n", me->name); - g_next_ipv4_id = system_time(); - return B_OK; - -} - -static status_t uninit(net_layer *me) -{ - printf("%s: uniniting layer\n", me->name); - return B_OK; -} - - -static status_t enable(net_layer *me, bool enable) -{ - return B_OK; -} - - -static status_t process_input(net_layer *me, net_buffer *buffer) -{ - uint16 *protocol; - - if (!buffer) - return B_ERROR; - - if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, 0, NULL, (void **) &protocol, NULL) != B_OK) - return B_ERROR; - - if (*protocol != htons(0x0800)) // IPv4 on Ethernet protocol value - return B_ERROR; - - // TODO! - dump_ipv4_header(buffer); - g_stack->delete_buffer(buffer, false); - - return B_OK; -} - -static status_t process_output(net_layer *me, net_buffer *buffer) -{ - if (!buffer) - return B_ERROR; - - // TODO! - return B_ERROR; -} - -// #pragma mark - - -status_t std_ops(int32 op, ...) -{ - switch(op) { - case B_MODULE_INIT: { - status_t status; - net_layer *layer; - - printf("ipv4: B_MODULE_INIT\n"); - status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); - if (status != B_OK) - return status; - - ethernet_protocol_attr = g_stack->string_to_token("ethernet:protocol"); - - status = g_stack->register_layer("IPv4", "ethernet/ipv4", 2, &nlmi, NULL, &layer); - if (status != B_OK) - goto error; - - return B_OK; - -error: - g_stack->unregister_layer(layer); - put_module(NET_STACK_MODULE_NAME); - return status; - } - - case B_MODULE_UNINIT: - printf("ipv4: B_MODULE_UNINIT\n"); - put_module(NET_STACK_MODULE_NAME); - break; - - default: - return B_ERROR; - } - return B_OK; -} - -struct net_layer_module_info nlmi = { - { - NET_MODULES_ROOT "protocols/ipv4/v0", - 0, - std_ops - }, - - NET_LAYER_API_VERSION, - - init, - uninit, - enable, - NULL, - process_input, - process_output -}; - -_EXPORT module_info *modules[] = { - (module_info*) &nlmi, // net_layer_module_info - NULL -}; diff --git a/src/tests/kits/net/new_stack/stack/Jamfile b/src/tests/kits/net/new_stack/stack/Jamfile deleted file mode 100644 index a3be9466ef..0000000000 --- a/src/tests/kits/net/new_stack/stack/Jamfile +++ /dev/null @@ -1,13 +0,0 @@ -SubDir HAIKU_TOP src tests kits net new_stack stack ; - -UseHeaders [ FDirName $(HAIKU_TOP) src tests kits net new_stack headers ] ; - -Addon stack : - stack.c - attribute.c - layers_manager.c - buffer.c - timer.c - dump.c - : new_stack_tester be -; diff --git a/src/tests/kits/net/new_stack/stack/attribute.c b/src/tests/kits/net/new_stack/stack/attribute.c deleted file mode 100644 index 282d51330d..0000000000 --- a/src/tests/kits/net/new_stack/stack/attribute.c +++ /dev/null @@ -1,210 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "net_stack.h" -#include "memory_pool.h" -#include "attribute.h" - -#define DPRINTF printf - -#define ATTRIBUTES_PER_POOL (64) - -static memory_pool *g_attributes_pool = NULL; -extern memory_pool_module_info *g_memory_pool; - -// Privates prototypes -// ------------------- - -// LET'S GO FOR IMPLEMENTATION -// ------------------------------------ - -status_t add_attribute(net_attribute **in_list, string_token id, int type, va_list args) -{ - net_attribute *attr; - - attr = new_attribute(in_list, id); - if (! attr) - return B_NO_MEMORY; - - attr->type = type; - switch(type & NET_ATTRIBUTE_TYPE_MASK) { - case NET_ATTRIBUTE_BOOL: - attr->u.boolean = va_arg(args, bool); - break; - - case NET_ATTRIBUTE_BYTE: - attr->u.byte = va_arg(args, uint8); - break; - - case NET_ATTRIBUTE_INT16: - attr->u.word = va_arg(args, uint16); - break; - - case NET_ATTRIBUTE_INT32: - attr->u.dword = va_arg(args, uint32); - break; - - case NET_ATTRIBUTE_INT64: - attr->u.ddword = va_arg(args, uint64); - break; - - case NET_ATTRIBUTE_DATA: - { // void *data, size_t data_len - void *data = va_arg(args, void *); - size_t sz = va_arg(args, size_t); - - if (sz > MAX_ATTRIBUTE_DATA_LEN) - sz = MAX_ATTRIBUTE_DATA_LEN; - - memcpy(attr->u.data, data, sz); - break; - } - - case NET_ATTRIBUTE_STRING: - strncpy(attr->u.data, va_arg(args, char *), MAX_ATTRIBUTE_DATA_LEN); - break; - - case NET_ATTRIBUTE_POINTER: - // NB: data behind pointer ARE NOT copied - attr->u.ptr = va_arg(args, void *); - break; - - case NET_ATTRIBUTE_IOVEC: - { // int nb, iovec *vec - int nb = va_arg(args, int); - iovec * vec = va_arg(args, iovec *); - if (nb > MAX_ATTRIBUTE_IOVECS) - nb = MAX_ATTRIBUTE_IOVECS; - - memcpy(&attr->u.vec, vec, nb * sizeof(iovec)); - break; - } - } - - return B_OK; -} - - -net_attribute * new_attribute(net_attribute **in_list, string_token id) -{ - net_attribute *attr; - - if (! g_attributes_pool) - g_attributes_pool = g_memory_pool->new_pool(sizeof(*attr), ATTRIBUTES_PER_POOL); - - if (! g_attributes_pool) - return NULL; - - attr = (net_attribute *) g_memory_pool->new_pool_node(g_attributes_pool); - if (! attr) - return NULL; - - attr->id = id; - attr->type = 0; - - if (in_list) { - // prepend this attribut to the list - attr->next = *in_list; - *in_list = attr; - } else - attr->next = NULL; - - return attr; - -} - -status_t delete_attribute(net_attribute *attr, net_attribute **from_list) -{ - if (! attr) - return B_BAD_VALUE; - - if (! g_attributes_pool) - // Uh? From where come this net_attribute!?! - return B_ERROR; - - // dprintf("delete_attribute(%p, %p)\n", attr, from_list); - - // Remove attribut from list, if any - if (from_list) { - if (*from_list == attr) - *from_list = attr->next; - else { - net_attribute *tmp = *from_list; - while (tmp) { - if (tmp->next == attr) - break; - tmp = tmp->next; - } - if (tmp) - tmp->next = attr->next; - } - } - - // Last, delete the net_buffer itself - return g_memory_pool->delete_pool_node(g_attributes_pool, attr); -} - - -net_attribute * find_attribute(net_attribute *list, string_token id, int index, - int *type, void **value, size_t *size) -{ - net_attribute *attr; - - if (! list) - return NULL; - - // dprintf("find_attribute(%p, %p)\n", list, id); - attr = list; - while (attr) { - if (attr->id == id && index-- == 0) { - if (type) *type = attr->type; - if (size) *size = attr->size; - if (value) { - switch (attr->type & NET_ATTRIBUTE_TYPE_MASK) { - case NET_ATTRIBUTE_BOOL: - *value = &attr->u.boolean; - break; - - case NET_ATTRIBUTE_BYTE: - *value = &attr->u.byte; - break; - - case NET_ATTRIBUTE_INT16: - *value = &attr->u.word; - break; - - case NET_ATTRIBUTE_INT32: - *value = &attr->u.dword; - break; - - case NET_ATTRIBUTE_INT64: - *value = &attr->u.ddword; - break; - - case NET_ATTRIBUTE_DATA: - case NET_ATTRIBUTE_STRING: - *value = &attr->u.data; - break; - - case NET_ATTRIBUTE_POINTER: - *value = attr->u.ptr; - break; - - case NET_ATTRIBUTE_IOVEC: - *value = &attr->u.vec; - break; - }; - }; - return attr; - }; - attr = attr->next; - }; - return NULL; -} - diff --git a/src/tests/kits/net/new_stack/stack/attribute.h b/src/tests/kits/net/new_stack/stack/attribute.h deleted file mode 100644 index 06752c65cf..0000000000 --- a/src/tests/kits/net/new_stack/stack/attribute.h +++ /dev/null @@ -1,48 +0,0 @@ -/* attribute.h - * private definitions for network attributes - */ - -#ifndef OBOS_NET_STACK_ATTRIBUTE_H -#define OBOS_NET_STACK_ATTRIBUTE_H - -#include -#include - -#include - -#include "net_stack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_ATTRIBUTE_IOVECS (16) -#define MAX_ATTRIBUTE_DATA_LEN (256) - -struct net_attribute { - struct net_attribute *next; - string_token id; - uint32 type; - size_t size; - union { - bool boolean; - uint8 byte; - uint16 word; - uint32 dword; - uint64 ddword; - char data[MAX_ATTRIBUTE_DATA_LEN]; // Beware: data max size is limited :-( - void *ptr; - iovec vec[MAX_ATTRIBUTE_IOVECS]; // Beware: these are limited too :-( - } u; -}; - -extern status_t add_attribute(net_attribute **in_list, string_token id, int type, va_list args); -extern net_attribute * new_attribute(net_attribute **in_list, string_token id); -extern status_t delete_attribute(net_attribute *attribut, net_attribute **from_list); -extern net_attribute * find_attribute(net_attribute *list, string_token id, int index, int *type, void **value, size_t *size); - -#ifdef __cplusplus -} -#endif - -#endif // OBOS_NET_STACK_ATTRIBUTE_H diff --git a/src/tests/kits/net/new_stack/stack/buffer.c b/src/tests/kits/net/new_stack/stack/buffer.c deleted file mode 100644 index c5dd84a8bd..0000000000 --- a/src/tests/kits/net/new_stack/stack/buffer.c +++ /dev/null @@ -1,1012 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "memory_pool.h" -#include "net_stack.h" -#include "dump.h" -#include "buffer.h" -#include "attribute.h" - -typedef struct net_buffer_chunk { - struct net_buffer_chunk *next; - struct net_buffer_chunk *next_data; - uint32 ref_count; // this data is referenced by 'ref_count' net_buffer_chunk(s) - const void *data; // address of data - size_t len; // in bytes (could be 0, with *guest* add_buffer_free_element() node - buffer_chunk_free_func free_func; // if NULL, don't free it! - void * free_cookie; // if != NULL, free_func(cookie, data) is called... otherwise, free_func(data) -} net_buffer_chunk; - -struct net_buffer { - struct net_buffer *next; // for chained buffers, like fifo'ed ones... - struct net_buffer_chunk *all_chunks; // unordored but ref counted net_buffer_chunk(s) linked list, to free on delete_data() - struct net_buffer_chunk *data_chunks; // ordered net_buffer_chunk(s) linked list - size_t len; // total bytes in this net_buffer - uint32 flags; - #define BUFFER_TO_FREE (1) - #define BUFFER_IS_URGENT (2) - net_attribute *attributes; // buffer attributes -}; - -struct net_buffer_queue { - benaphore lock; - sem_id sync; - volatile int32 waiting; - volatile int32 interrupt; - - size_t max_bytes; - size_t current_bytes; - - net_buffer *head; - net_buffer *tail; -}; - - -#define DPRINTF printf - -#define BUFFERS_PER_POOL (64) -#define BUFFER_CHUNKS_PER_POOL (256) - -static memory_pool * g_buffers_pool = NULL; -static memory_pool * g_buffer_chunks_pool = NULL; - -static thread_id g_buffers_purgatory_thread = -1; -static volatile sem_id g_buffers_purgatory_sync = -1; // use to notify buffers purgatory thread that some net_buffers need to be deleted (interrupt safely...) - -#define BUFFER_QUEUES_PER_POOL 16 - -static memory_pool * g_buffer_queues_pool = NULL; - -extern memory_pool_module_info *g_memory_pool; - -// Privates prototypes -// ------------------- - -static net_buffer_chunk * new_buffer_chunk(const void *data, size_t len); -static net_buffer_chunk * find_buffer_chunk(net_buffer *buffer, uint32 offset, uint32 *offset_in_chunk, net_buffer_chunk **previous_chunk); - -static status_t prepend_buffer(net_buffer *buffer, const void *data, size_t bytes, buffer_chunk_free_func freethis); -static status_t append_buffer(net_buffer *buffer, const void *data, size_t bytes, buffer_chunk_free_func freethis); - -static int32 buffers_purgatory_thread(void * data); - -static status_t buffer_killer(memory_pool * pool, void * node, void * cookie); -static status_t buffer_queue_killer(memory_pool * pool, void * node, void * cookie); - - -// LET'S GO FOR IMPLEMENTATION -// ------------------------------------ - - -// -------------------------------------------------- -status_t start_buffers_service() -{ - g_buffers_purgatory_sync = create_sem(0, "net buffers purgatory"); -#ifdef _KERNEL_MODE - set_sem_owner(g_buffers_purgatory_sync, B_SYSTEM_TEAM); -#endif - - // fire buffers_purgatory_thread - g_buffers_purgatory_thread = spawn_kernel_thread(buffers_purgatory_thread, "buffers serial killer", B_LOW_PRIORITY, 0); - if (g_buffers_purgatory_thread < B_OK) - return g_buffers_purgatory_thread; - - puts("net buffers service started."); - - return resume_thread(g_buffers_purgatory_thread); -} - - -// -------------------------------------------------- -status_t stop_buffers_service() -{ - status_t status; - - // Free all buffers queues inner stuff (sem, locker, etc) - g_memory_pool->for_each_pool_node(g_buffer_queues_pool, buffer_queue_killer, NULL); - g_memory_pool->delete_pool(g_buffer_queues_pool); - g_buffer_queues_pool = NULL; - - // this would stop buffers_purgatory_thread - delete_sem(g_buffers_purgatory_sync); - g_buffers_purgatory_sync = -1; - wait_for_thread(g_buffers_purgatory_thread, &status); - - // As the purgatory thread stop, some net_buffer(s) still could be flagged - // PACKET_TO_FREE, but not deleted... yet. - g_memory_pool->for_each_pool_node(g_buffers_pool, buffer_killer, NULL); - - // free buffers-related pools - g_memory_pool->delete_pool(g_buffers_pool); - g_memory_pool->delete_pool(g_buffer_chunks_pool); - - g_buffers_pool = NULL; - g_buffer_chunks_pool = NULL; - - puts("net buffers service stopped."); - - return B_OK; -} - - -// #pragma mark - - - -// -------------------------------------------------- -net_buffer * new_buffer(void) -{ - net_buffer *buffer; - - if (! g_buffers_pool) - g_buffers_pool = g_memory_pool->new_pool(sizeof(*buffer), BUFFERS_PER_POOL); - - if (! g_buffers_pool) - return NULL; - - buffer = (net_buffer *) g_memory_pool->new_pool_node(g_buffers_pool); - if (! buffer) - return NULL; - - buffer->next = NULL; - buffer->data_chunks = NULL; - buffer->all_chunks = NULL; - buffer->attributes = NULL; - buffer->len = 0; - buffer->flags = 0; - - return buffer; -} - - - -// -------------------------------------------------- -status_t delete_buffer(net_buffer *buffer, bool interrupt_safe) -{ - if (! buffer) - return B_BAD_VALUE; - - if (! g_buffers_pool) - // Uh? From where come this net_buffer!?! - return B_ERROR; - - printf("delete_buffer(%p)\n", buffer); - - if (interrupt_safe) { - // We're called from a interrupt handler. Don't use any blocking calls (delete_pool_node() is!) - // We flag this net_buffer as to be free by the buffers purgatory thread - // Notify him that he have a new buffer purgatory candidate - // (notice the B_DO_NOT_RESCHEDULE usage, the only release_sem_etc() interrupt-safe mode) - buffer->flags |= BUFFER_TO_FREE; - return release_sem_etc(g_buffers_purgatory_sync, 1, B_DO_NOT_RESCHEDULE); - }; - - if (buffer->all_chunks) { - // Okay, we can (try to) free each buffer chunk(s) right now! - - net_buffer_chunk *chunk; - net_buffer_chunk *next_chunk; - - chunk = buffer->all_chunks; - while (chunk) { - // okay, one net_buffer_chunk less referencing this data - atomic_add(&chunk->ref_count, -1); - next_chunk = chunk->next; - - if (chunk->ref_count == 0) { - // it was the last net_buffer_chunk to reference this data, - // so free it now! - - // do we have to call the free_func() on this data? - if (chunk->free_func) { - // yes, please!!! - // call the right free_func kind on this data - if (chunk->free_cookie) - chunk->free_func(chunk->free_cookie, (void *) chunk->data); - else - chunk->free_func((void *) chunk->data); - }; - // delete this net_buffer_chunk - g_memory_pool->delete_pool_node(g_buffer_chunks_pool, chunk); - }; - - chunk = next_chunk; - }; - }; - - if (buffer->attributes) { - // Free buffer attributes - - net_attribute *attr; - net_attribute *next_attr; - - attr = buffer->attributes; - while (attr) { - next_attr = attr->next; - delete_attribute(attr, NULL); - attr = next_attr; - }; - }; - - // Last, delete the net_buffer itself - return g_memory_pool->delete_pool_node(g_buffers_pool, buffer); -} - - -// -------------------------------------------------- -net_buffer * duplicate_buffer(net_buffer *buffer) -{ - return NULL; // B_UNSUPPORTED; -} - - -// -------------------------------------------------- -net_buffer * clone_buffer(net_buffer *buffer) -{ - net_buffer *clone; - net_buffer_chunk *chunk; - - if (! g_buffers_pool) - g_buffers_pool = g_memory_pool->new_pool(sizeof(*buffer), BUFFERS_PER_POOL); - - if (! g_buffers_pool) - return NULL; - - clone = (net_buffer *) g_memory_pool->new_pool_node(g_buffers_pool); - if (! clone) - return NULL; - - clone->next = NULL; - clone->data_chunks = buffer->data_chunks; - clone->all_chunks = buffer->all_chunks; - clone->len = buffer->len; - clone->flags = buffer->flags; - - // Okay, increase all chunks ref count, as we have another buffer referencing them - chunk = buffer->all_chunks; - while (chunk) { - // okay, one net_buffer_chunk less referencing this data - atomic_add(&chunk->ref_count, 1); - chunk = chunk->next; - }; - - return clone; -} - - -// -------------------------------------------------- -net_buffer * split_buffer(net_buffer *buffer, uint32 offset) -{ - return NULL; // B_UNSUPPORTED; -} - -// -------------------------------------------------- -status_t merge_buffers(net_buffer *begin_buffer, net_buffer *end_buffer) -{ - return B_ERROR; -} - - -// -------------------------------------------------- -status_t attach_buffer_free_element(net_buffer *buffer, void *arg1, void *arg2, buffer_chunk_free_func freethis) -{ - net_buffer_chunk *chunk; - - if (! buffer) - return B_BAD_VALUE; - - chunk = new_buffer_chunk(arg1, 0); // unknown data length - if (! chunk) - return B_ERROR; - - chunk->next_data = NULL; // not a data_chunks member, just a *guest star* all_chunks member - chunk->free_func = freethis; - chunk->free_cookie = arg2; - - // add to all_chunks (chunks order don't matter in this list :-) - chunk->next = buffer->all_chunks; - buffer->all_chunks = chunk; - - return B_OK; -} - - -// -------------------------------------------------- -status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis) -{ - net_buffer_chunk *previous_chunk; - net_buffer_chunk *next_chunk; - net_buffer_chunk *split_chunk; - net_buffer_chunk *new_chunk; - uint32 offset_in_chunk; - - if (offset == 0) - return prepend_buffer(buffer, data, bytes, freethis); - - if (offset >= buffer->len) - return append_buffer(buffer, data, bytes, freethis); - - if (! buffer) - return B_BAD_VALUE; - - if (bytes < 1) - return B_BAD_VALUE; - - - next_chunk = find_buffer_chunk(buffer, offset, &offset_in_chunk, &previous_chunk); - if (! next_chunk) - return B_BAD_VALUE; - - split_chunk = NULL; - new_chunk = NULL; - - if (offset_in_chunk) { - // we must split next_chunk data in two parts :-( - uint8 *split; - - split = (uint8 *) next_chunk->data; - split += offset_in_chunk; - split_chunk = new_buffer_chunk(split, next_chunk->len - offset_in_chunk); - if (! split_chunk) - goto error1; - - next_chunk->len = offset_in_chunk; // cut the data len of original chunk - - // as split_chunk data comes from 'next_chunk', we don't - // ask to free this chunk data, as it would be by previous_chunk - split_chunk->free_func = NULL; - - // add the split_chunk to buffer's all_chunks list - split_chunk->next = buffer->all_chunks; - buffer->all_chunks = split_chunk; - - // insert the split_chunk between the two part of the *splitted* next_chunk - split_chunk->next_data = next_chunk->next_data; - next_chunk->next_data = split_chunk; - - previous_chunk = next_chunk; - next_chunk = split_chunk; - }; - - // create a new chunk to host inserted data - new_chunk = new_buffer_chunk(data, bytes); - if (! new_chunk) - goto error2; - - new_chunk->free_func = freethis; // can be NULL = don't free this chunk - new_chunk->free_cookie = NULL; - - // add the new_chunk to buffer's all_chunks list - new_chunk->next = buffer->all_chunks; - buffer->all_chunks = new_chunk; - - // Insert this new_chunk between previous and next chunk - previous_chunk->next_data = new_chunk; - new_chunk->next_data = next_chunk; - - buffer->len += bytes; - - return B_OK; - -error2: - g_memory_pool->delete_pool_node(g_buffer_chunks_pool, new_chunk); -error1: - g_memory_pool->delete_pool_node(g_buffer_chunks_pool, split_chunk); - return B_ERROR; -} - - -// -------------------------------------------------- -status_t remove_from_buffer(net_buffer *buffer, uint32 offset, size_t bytes) -{ - net_buffer_chunk *first_chunk; - net_buffer_chunk *last_chunk; - net_buffer_chunk *previous_chunk; - uint32 offset_in_first_chunk; - uint32 offset_in_last_chunk; - - if (! buffer) - return B_BAD_VALUE; - - if (offset >= buffer->len) - return B_BAD_VALUE; - - if (bytes < 1) - return B_BAD_VALUE; - - first_chunk = find_buffer_chunk(buffer, offset, &offset_in_first_chunk, &previous_chunk); - if (! first_chunk) - return B_BAD_VALUE; - - last_chunk = find_buffer_chunk(buffer, offset + bytes, &offset_in_last_chunk, NULL); - if (! last_chunk) - return B_BAD_VALUE; - - if (offset_in_last_chunk) { - // we must split last_chunk data in two parts, - // removing beginnin chunk from data lists and adding the ending one :-( - - net_buffer_chunk *split_chunk; - uint8 *split; - - // remove the beginning of last_chunk data - - split = (uint8 *) last_chunk->data; - split += offset_in_last_chunk; - split_chunk = new_buffer_chunk(split, last_chunk->len - offset_in_last_chunk); - // if (! split_chunk) - // goto error1; - // as split_chunk data comes from 'last_chunk', we don't - // ask to free this chunk data, as it would be by previous_chunk - split_chunk->free_func = NULL; - split_chunk->next_data = last_chunk->next_data; - - // add the split_chunk to buffer's all_chunks list - split_chunk->next = buffer->all_chunks; - buffer->all_chunks = split_chunk; - - last_chunk = split_chunk; - }; - - if (offset_in_first_chunk) { - // remove the end of first_chunk data: just forgot about last bytes of data :-) - first_chunk->len = offset_in_first_chunk; - } else - first_chunk = previous_chunk; - - // fix the data chunks list to remove chunk(s), if any - if (first_chunk) - first_chunk->next_data = last_chunk; - else - buffer->data_chunks = last_chunk; - - buffer->len -= bytes; - return B_OK; -} - - -// -------------------------------------------------- -size_t read_buffer(net_buffer *buffer, uint32 offset, void *data, size_t bytes) -{ - net_buffer_chunk *chunk; - uint32 offset_in_chunk; - size_t len; - size_t chunk_len; - uint8 *from; - uint8 *to; - - to = (uint8 *) data; - len = 0; - - chunk = find_buffer_chunk(buffer, offset, &offset_in_chunk, NULL); - while (chunk) { - from = (uint8 *) chunk->data; - from += offset_in_chunk; - chunk_len = min((chunk->len - offset_in_chunk), (bytes - len)); - - memcpy(to, from, chunk_len); - - len += chunk_len; - if (len >= bytes) - break; - - to += chunk_len; - offset_in_chunk = 0; // only the first chunk - - chunk = chunk->next_data; // next chunk - }; - - return len; -} - - -// -------------------------------------------------- -size_t write_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes) -{ - net_buffer_chunk *chunk; - uint32 offset_in_chunk; - size_t len; - size_t chunk_len; - uint8 *from; - uint8 *to; - - from = (uint8 *) data; - len = 0; - - chunk = find_buffer_chunk(buffer, offset, &offset_in_chunk, NULL); - if (! chunk) - return B_ERROR; - - while (chunk) { - to = (uint8 *) chunk->data; - to += offset_in_chunk; - chunk_len = min((chunk->len - offset_in_chunk), (bytes - len)); - - memcpy(to, from, chunk_len); - - len += chunk_len; - if (len >= bytes) - break; - - from += chunk_len; - offset_in_chunk = 0; // only the first chunk - - chunk = chunk->next_data; // next chunk - }; - - return len; -} - -// #pragma mark - - -// -------------------------------------------------- -status_t add_buffer_attribute(net_buffer *buffer, string_token id, int type, ...) -{ - status_t status; - va_list args; - - if (! buffer) - return B_BAD_VALUE; - - if (type & FROM_BUFFER) { - net_attribute *attr; - net_buffer_chunk *chunk; - uint32 offset; - uint32 offset_in_chunk; - size_t size; - uint8 *ptr; - - va_start(args, type); - offset = va_arg(args, uint32); - size = va_arg(args, size_t); - va_end(args); - - chunk = find_buffer_chunk(buffer, offset, &offset_in_chunk, NULL); - if (chunk == NULL) - return B_BAD_VALUE; - - attr = new_attribute(&buffer->attributes, id); - if (! attr) - return B_NO_MEMORY; - - attr->size = size; - if (size < chunk->len - offset_in_chunk) { - ptr = (uint8 *) chunk->data; - ptr += offset_in_chunk; - - attr->type = type | NET_ATTRIBUTE_POINTER; - attr->u.ptr = ptr; - } else { - // data overlap this chunk, use iovec attribute type - int i; - uint32 len; - uint32 chunk_len; - - i = 0; - len = 0; - while (chunk) { - ptr = (uint8 *) chunk->data; - ptr += offset_in_chunk; - chunk_len = min((chunk->len - offset_in_chunk), (size - len)); - - attr->u.vec[i].iov_base = ptr; - attr->u.vec[i].iov_len = chunk_len; - - len += chunk_len; - i++; - if (len >= size || i > 16) - break; - - offset_in_chunk = 0; // only the first chunk - - chunk = chunk->next_data; // next chunk - }; - - attr->type = type | NET_ATTRIBUTE_IOVEC; - }; - - status = B_OK; - - } else { - // default attribute types - va_start(args, type); - status = add_attribute(&buffer->attributes, id, type, args); - va_end(args); - }; - - return status; -} - - -// -------------------------------------------------- -status_t remove_buffer_attribute(net_buffer *buffer, string_token id, int index) -{ - net_attribute *attr; - - if (! buffer) - return B_BAD_VALUE; - - attr = find_attribute(buffer->attributes, id, index, NULL, NULL, NULL); - if (! attr) - return B_NAME_NOT_FOUND; - - return delete_attribute(attr, &buffer->attributes); -} - - -status_t find_buffer_attribute(net_buffer *buffer, string_token id, int index, int *type, void **value, size_t *size) -{ - net_attribute *attr; - - if (! buffer) - return B_BAD_VALUE; - - attr = find_attribute(buffer->attributes, id, index, type, value, size); - if (! attr) - return B_NAME_NOT_FOUND; - - return B_OK; -} - - -// #pragma mark - - -// -------------------------------------------------- -net_buffer_queue * new_buffer_queue(size_t max_bytes) -{ - net_buffer_queue *queue; - - if (! g_buffer_queues_pool) - g_buffer_queues_pool = g_memory_pool->new_pool(sizeof(net_buffer_queue), BUFFER_QUEUES_PER_POOL); - - if (! g_buffer_queues_pool) - return NULL; - - queue = (net_buffer_queue *) g_memory_pool->new_pool_node(g_buffer_queues_pool); - if (! queue) - return NULL; - - create_benaphore(&queue->lock, "net_buffer_queue lock"); - queue->sync = create_sem(0, "net_buffer_queue sem"); - - queue->max_bytes = max_bytes; - queue->current_bytes = 0; - - queue->head = queue->tail = NULL; - - return queue; -} - - -// -------------------------------------------------- -status_t delete_buffer_queue(net_buffer_queue *queue) -{ - status_t status; - - if (! queue) - return B_BAD_VALUE; - - if (! g_buffer_queues_pool) - // Uh? From where come this queue then!?! - return B_ERROR; - - // free the net_buffer's (still) in this queue - status = empty_buffer_queue(queue); - if (status != B_OK) - return status; - - delete_sem(queue->sync); - delete_benaphore(&queue->lock); - - return g_memory_pool->delete_pool_node(g_buffer_queues_pool, queue); -} - - -// -------------------------------------------------- -status_t empty_buffer_queue(net_buffer_queue *queue) -{ - net_buffer *buffer; - net_buffer *next_buffer; - - if (! queue) - return B_BAD_VALUE; - - lock_benaphore(&queue->lock); - - buffer = queue->head; - while (buffer) { - next_buffer = buffer->next; - delete_buffer(buffer, true); - buffer = next_buffer; - }; - - queue->head = NULL; - queue->tail = NULL; - - delete_sem(queue->sync); - queue->sync = create_sem(0, "net_buffer_queue sem"); - - unlock_benaphore(&queue->lock); - return B_OK; -} - - -// -------------------------------------------------- -status_t enqueue_buffer(net_buffer_queue *queue, net_buffer *buffer) -{ - if (! queue) - return B_BAD_VALUE; - - if (! buffer) - return B_BAD_VALUE; - - buffer->next = NULL; - -/* - if (queue->current_bytes + buffer->len > queue->max_bytes) - // what to do? dump some enqueued buffer(s) to free space? drop the new net_buffer? - // TODO: dequeue enought net_buffer(s) to free space to queue this one... - NULL; -*/ - lock_benaphore(&queue->lock); - - if (! queue->head) - queue->head = buffer; - if (queue->tail) - queue->tail->next = buffer; - queue->tail = buffer; - - queue->current_bytes += buffer->len; - - unlock_benaphore(&queue->lock); - - return release_sem_etc(queue->sync, 1, B_DO_NOT_RESCHEDULE); -} - - -// -------------------------------------------------- -size_t dequeue_buffer(net_buffer_queue *queue, net_buffer **buffer, bigtime_t timeout, bool peek) -{ - status_t status; - net_buffer *head_buffer; - - if (! queue) - return B_BAD_VALUE; - - status = acquire_sem_etc(queue->sync, 1, B_RELATIVE_TIMEOUT, timeout); - if (status != B_OK) - return status; - - lock_benaphore(&queue->lock); - - head_buffer = queue->head; - - if (! peek) { - // detach the head net_buffer from this fifo - queue->head = head_buffer->next; - if (queue->tail == head_buffer) - queue->tail = queue->head; - - queue->current_bytes -= head_buffer->len; - - head_buffer->next = NULL; // we never know :-) - }; - - unlock_benaphore(&queue->lock); - - *buffer = head_buffer; - - return head_buffer->len; -} - - -// #pragma mark - - -// -------------------------------------------------- -static net_buffer_chunk * new_buffer_chunk(const void *data, uint32 len) -{ - net_buffer_chunk *chunk; - - if (! g_buffer_chunks_pool) - g_buffer_chunks_pool = g_memory_pool->new_pool(sizeof(net_buffer_chunk), BUFFER_CHUNKS_PER_POOL); - - if (! g_buffer_chunks_pool) - return NULL; - - chunk = (net_buffer_chunk *) g_memory_pool->new_pool_node(g_buffer_chunks_pool); - - chunk->data = data; - chunk->len = len; - - chunk->ref_count = 1; - - chunk->free_cookie = NULL; - chunk->free_func = NULL; - - chunk->next = NULL; - chunk->next_data = NULL; - - return chunk; -} - - -// -------------------------------------------------- -static net_buffer_chunk * find_buffer_chunk(net_buffer *buffer, uint32 offset, uint32 *offset_in_chunk, net_buffer_chunk **previous_chunk) -{ - net_buffer_chunk *previous; - net_buffer_chunk *chunk; - uint32 len; - - if (! buffer) - return NULL; - - if (buffer->len <= offset) - // this net_buffer don't hold enough data to reach this offset! - return NULL; - - len = 0; - chunk = buffer->data_chunks; - previous = NULL; - while (chunk) { - len += chunk->len; - - if(offset < len) - break; - - previous = chunk; - chunk = chunk->next_data; - }; - - if (offset_in_chunk) - *offset_in_chunk = chunk->len - (len - offset); - if (previous_chunk) - *previous_chunk = previous; - - return chunk; -} - -// -------------------------------------------------- -static status_t prepend_buffer(net_buffer *buffer, const void *data, uint32 bytes, buffer_chunk_free_func freethis) -{ - net_buffer_chunk *chunk; - - if (! buffer) - return B_BAD_VALUE; - - if (bytes < 1) - return B_BAD_VALUE; - - // create a new chunk to host the prepending data - chunk = new_buffer_chunk(data, bytes); - if (! chunk) - return B_ERROR; - - chunk->free_func = freethis; // can be NULL = don't free this chunk - chunk->free_cookie = NULL; - - // add this chunk to all_chunks (chunks order don't matter in this list, so we do it the easy way :-) - chunk->next = buffer->all_chunks; - buffer->all_chunks = chunk; - - // prepend this chunk to the data_chunks list: - chunk->next_data = buffer->data_chunks; - buffer->data_chunks = chunk; - - buffer->len += bytes; - - return B_OK; -} - - -// -------------------------------------------------- -static status_t append_buffer(net_buffer *buffer, const void *data, uint32 bytes, buffer_chunk_free_func freethis) -{ - net_buffer_chunk *chunk; - - if (! buffer) - return B_BAD_VALUE; - - if (bytes < 1) - return B_BAD_VALUE; - - // create a new chunk to host the appending data - chunk = new_buffer_chunk(data, bytes); - if (! chunk) - return B_ERROR; - - chunk->free_func = freethis; // can be NULL = don't free this chunk - chunk->free_cookie = NULL; - - // add this chunk to all_chunks (chunks order don't matter in this list, so we do it the easy way :-) - chunk->next = buffer->all_chunks; - buffer->all_chunks = chunk; - - // Add this chunk to the end of data_chunks list - chunk->next_data = NULL; - if (buffer->data_chunks) { - net_buffer_chunk *tmp; - - tmp = buffer->data_chunks; - while(tmp->next_data) // search the last net_buffer_chunk in list - tmp = tmp->next_data; - tmp->next_data = chunk; - } else - buffer->data_chunks = chunk; - - buffer->len += bytes; - - return B_OK; -} - - -// -------------------------------------------------- -void dump_buffer(net_buffer *buffer) -{ - net_buffer_chunk *chunk; - - if (! buffer) - return; - - DPRINTF("---- net_buffer %p: total len %ld\n", buffer, buffer->len); - - DPRINTF("data_chunks:\n"); - chunk = buffer->data_chunks; - while (chunk) { - DPRINTF(" * chunk %p: data %p, len %ld\n", chunk, chunk->data, chunk->len); - dump_memory(" ", chunk->data, chunk->len); - DPRINTF(" next: %p\n", chunk->next_data); - - chunk = chunk->next_data; - }; - - DPRINTF("all_chunks:\n"); - chunk = buffer->all_chunks; - while (chunk) { - DPRINTF(" * chunk %p: data %p, len %ld, ref_count %ld\n", chunk, chunk->data, chunk->len, chunk->ref_count); - if (chunk->free_func) - DPRINTF(" free_func: %p, free_cookie %p\n", chunk->free_func, chunk->free_cookie); - DPRINTF(" next: %p\n", chunk->next); - - chunk = chunk->next; - }; - -} - -// #pragma mark - - -// -------------------------------------------------- -static int32 buffers_purgatory_thread(void *data) -{ - while (true) { - if (acquire_sem(g_buffers_purgatory_sync) != B_OK) - break; - - // okay, time to cleanup some net_buffer(s) - g_memory_pool->for_each_pool_node(g_buffers_pool, buffer_killer, NULL); - }; - return 0; -} - - -// -------------------------------------------------- -static status_t buffer_killer(memory_pool * pool, void * node, void * cookie) -{ - net_buffer *buffer = node; - if (buffer->flags & BUFFER_TO_FREE) - delete_buffer(buffer, false); - - return 0; // B_OK; -} - - -// -------------------------------------------------- -static status_t buffer_queue_killer(memory_pool * pool, void * node, void * cookie) -{ - return delete_buffer_queue((net_buffer_queue *) node); -} - diff --git a/src/tests/kits/net/new_stack/stack/buffer.h b/src/tests/kits/net/new_stack/stack/buffer.h deleted file mode 100644 index d6a4dd30cb..0000000000 --- a/src/tests/kits/net/new_stack/stack/buffer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* buffer.h - * private definitions for network buffers support - */ - -#ifndef OBOS_NET_STACK_BUFFER_H -#define OBOS_NET_STACK_BUFFER_H - -#include - -#include "net_stack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern status_t start_buffers_service(void); -extern status_t stop_buffers_service(void); - -// Network buffer(s) -extern net_buffer * new_buffer(void); -extern status_t delete_buffer(net_buffer *buffer, bool interrupt_safe); - -extern net_buffer * duplicate_buffer(net_buffer *from); -extern net_buffer * clone_buffer(net_buffer *from); -extern net_buffer * split_buffer(net_buffer *from, uint32 offset); -extern status_t merge_buffers(net_buffer *begin, net_buffer *end); - -extern status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis); -extern status_t remove_from_buffer(net_buffer *buffer, uint32 offset, size_t bytes); - -extern status_t attach_buffer_free_element(net_buffer *buffer, void *arg1, void *arg2, buffer_chunk_free_func freethis); - -extern size_t read_buffer(net_buffer *buffer, uint32 offset, void *data, size_t bytes); -extern size_t write_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes); - -extern status_t add_buffer_attribute(net_buffer *buffer, string_token id, int type, ...); -extern status_t remove_buffer_attribute(net_buffer *buffer, string_token id, int index); -extern status_t find_buffer_attribute(net_buffer *buffer, string_token id, int index, int *type, void **value, size_t *size); - -extern void dump_buffer(net_buffer *buffer); - -// Network buffer(s) queue(s) -extern net_buffer_queue * new_buffer_queue(size_t max_bytes); -extern status_t delete_buffer_queue(net_buffer_queue *queue); - -extern status_t empty_buffer_queue(net_buffer_queue *queue); -extern status_t enqueue_buffer(net_buffer_queue *queue, net_buffer *buffer); -extern size_t dequeue_buffer(net_buffer_queue *queue, net_buffer **buffer, bigtime_t timeout, bool peek); - -#ifdef __cplusplus -} -#endif - -#endif // OBOS_NET_STACK_BUFFER_H diff --git a/src/tests/kits/net/new_stack/stack/dump.c b/src/tests/kits/net/new_stack/stack/dump.c deleted file mode 100644 index 018cd0e127..0000000000 --- a/src/tests/kits/net/new_stack/stack/dump.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -#include -#include - -#include "dump.h" - -// -------------------------------------------------- -void dump_memory(const char *prefix, const void *data, size_t len) -{ - uint32 i,j; - char text[96]; // only 3*16 + 3 + 16 max by line needed - uint8 *byte; - char *ptr; - - byte = (uint8 *) data; - - for ( i = 0; i < len; i += 16 ) { - ptr = text; - - for ( j = i; j < i+16 ; j++ ) { - if ( j < len ) - sprintf(ptr, "%02x ", byte[j]); - else - sprintf(ptr, " "); - ptr += 3; - }; - - strcat(ptr, "| "); - ptr += 2; - - for (j = i; j < len && j < i+16;j++) { - if ( byte[j] >= 0x20 && byte[j] < 0x7e ) - *ptr = byte[j]; - else - *ptr = '.'; - - ptr++; - }; - *ptr = '\n'; - ptr++; - *ptr = '\0'; - - if (prefix) - dprintf(prefix); - dprintf(text); - - // next line - }; -} diff --git a/src/tests/kits/net/new_stack/stack/dump.h b/src/tests/kits/net/new_stack/stack/dump.h deleted file mode 100644 index acca4c52df..0000000000 --- a/src/tests/kits/net/new_stack/stack/dump.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef DUMP_H -#define DUMP_H - -#include - -extern void dump_memory(const char *prefix, const void *data, size_t len); - -#endif diff --git a/src/tests/kits/net/new_stack/stack/layers_manager.c b/src/tests/kits/net/new_stack/stack/layers_manager.c deleted file mode 100644 index 2462c1366c..0000000000 --- a/src/tests/kits/net/new_stack/stack/layers_manager.c +++ /dev/null @@ -1,469 +0,0 @@ -/* layers_manager.c */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "memory_pool.h" -#include "layers_manager.h" -#include "buffer.h" -#include "attribute.h" -#include "stack.h" // for string_{to|for}_token() - -struct layers_list { - struct net_layer *first; - sem_id lock; -}; - -static struct layers_list g_layers; - -static memory_pool * g_layers_pool = NULL; -#define LAYERS_PER_POOL (64) - -static net_layer * new_layer(const char *name, const char *type, int priority, - net_layer_module_info *module, void *cookie); -static status_t delete_layer(net_layer *layer); - -extern memory_pool_module_info *g_memory_pool; - -string_token g_joker_token = 0; -string_token g_layers_trace_attr = 0; - -// -------------------------------------------------- -status_t start_layers_manager(void) -{ - void *module_list; - net_layer *layer; - - g_joker_token = string_to_token("*"); - g_layers_trace_attr = string_to_token("layers_trace"); - - g_layers.first = NULL; - - g_layers.lock = create_sem(1, "net_layers list lock"); - if (g_layers.lock < B_OK) - return B_ERROR; - -#ifdef _KERNEL_MODE - set_sem_owner(g_layers.lock, B_SYSTEM_TEAM); -#endif - - // Load all network/* modules and let them - // register any layer they may support by calling init() - module_list = open_module_list(NET_MODULES_ROOT); - if (module_list) { - size_t sz; - char module_name[256]; - struct net_layer_module_info *nlmi; - - sz = sizeof(module_name); - while (read_next_module_name(module_list, module_name, &sz) == B_OK) { - sz = sizeof(module_name); - if (!strlen(module_name)) - continue; - - if (strcmp(module_name, NET_STACK_MODULE_NAME) == 0) - continue; // skip ourself! ;-) - - dprintf("layers_manager: loading %s layer(s) module\n", module_name); - if (get_module(module_name, (module_info **) &nlmi) != B_OK) - continue; - - // this module may have been acquire more time if he called register_layer(), - // or have a B_KEEP_LOADED flag, so we don't care... - put_module(module_name); - }; - close_module_list(module_list); - }; - - // auto-start layer(s) - acquire_sem(g_layers.lock); - layer = g_layers.first; - while (layer) { - layer->module->init(layer); - layer->module->enable(layer, true); - layer = layer->next; - }; - release_sem(g_layers.lock); - - puts("net layers manager started."); - return B_OK; -} - -// -------------------------------------------------- -status_t stop_layers_manager(void) -{ - net_layer *layer, *next; - const char *module_name; - - delete_sem(g_layers.lock); - g_layers.lock = -1; - - // TODO: handle multiple layers registered by same net module - - // disable all layers... - layer = g_layers.first; - while (layer) { - next = layer->next; - module_name = layer->module->info.name; - dprintf("layers_manager: uniniting '%s' layer\n", layer->name); - // down the layer if currently up - layer->module->enable(layer, false); - layer->module->uninit(layer); - - delete_layer(layer); - - dprintf("layers_manager: unloading %s layer(s) module\n", module_name); - put_module(module_name); - - layer = next; - }; - - puts("net layers manager stopped."); - - return B_OK; -} - - - -// #pragma mark - - -// -------------------------------------------------- -status_t register_layer(const char *name, const char *type, int priority, - net_layer_module_info *module, void *cookie, net_layer **_layer) -{ - status_t status; - module_info *dummy; - net_layer *layer; - - if (name == NULL || - strlen(name) <= 0 || - module == NULL) - return B_ERROR; - - layer = new_layer(name, type, priority, module, cookie); - if (!layer) - return B_NO_MEMORY; - - // acquire this module, to keep it loaded while this layer is registered - status = get_module(module->info.name, &dummy); - if (status != B_OK) - goto error1; - - status = acquire_sem(g_layers.lock); - if (status != B_OK) - goto error2; - - layer->next = g_layers.first; - g_layers.first = layer; - - release_sem(g_layers.lock); - - dprintf("layers_manager: '%s' layer, registering '%s/%s' type\n", layer->name, - string_for_token(layer->type), string_for_token(layer->sub_type)); - - if (_layer) - *_layer = layer; - return B_OK; - -error2: - put_module(module->info.name); -error1: - return status; -} - - - -// -------------------------------------------------- -status_t unregister_layer(net_layer *layer) -{ - status_t status; - - if (!layer) - return B_ERROR; - - status = acquire_sem(g_layers.lock); - if (status != B_OK) - return status; - - if (g_layers.first == layer) - g_layers.first = layer->next; - else { - net_layer * p = g_layers.first; - while (p && p->next != layer) - p = p->next; - - if (!p) { - // Oh oh... :-( - dprintf("layers_manager: unregister_layer(): %p layer not found in list!\n", layer); - release_sem(g_layers.lock); - return B_ERROR; - }; - - p->next = layer->next; - }; - release_sem(g_layers.lock); - - layer->module->uninit(layer); - - dprintf("layers_manager: '%s' layer unregistered\n", layer->name); - - put_module(layer->module->info.name); - - return delete_layer(layer); -} - - -// -------------------------------------------------- -net_layer * find_layer(const char *name) -{ - net_layer *layer; - status_t status; - - if (!name) - return NULL; - - status = acquire_sem(g_layers.lock); - if (status != B_OK) - return NULL; - - layer = g_layers.first; - while (layer) { - if (strcmp(layer->name, name) == 0) - break; - layer = layer->next; - } - release_sem(g_layers.lock); - return layer; -} - -// #pragma mark - - -// -------------------------------------------------- -status_t add_layer_attribute(net_layer *layer, const void *id, int type, ...) -{ - status_t status; - va_list args; - - va_start(args, type); - status = add_attribute(&layer->attributes, id, type, args); - va_end(args); - - return status; -} - - -// -------------------------------------------------- -status_t remove_layer_attribute(net_layer *layer, const void *id, int index) -{ - net_attribute *attr; - - if (! layer) - return B_BAD_VALUE; - - attr = find_attribute(layer->attributes, id, index, NULL, NULL, NULL); - if (! attr) - return B_NAME_NOT_FOUND; - - return delete_attribute(attr, &layer->attributes); -} - -status_t find_layer_attribute(net_layer *layer, const void *id, int index, int *type, - void **value, size_t *size) -{ - net_attribute *attr; - - if (! layer) - return B_BAD_VALUE; - - attr = find_attribute(layer->attributes, id, index, type, value, size); - if (! attr) - return B_NAME_NOT_FOUND; - - return B_OK; -} - -// #pragma mark - - -// -------------------------------------------------- -status_t send_layers_up(net_layer *layer, net_buffer *buffer) -{ - net_layer *above; - status_t status; - // int i; - - if (!layer) - return B_ERROR; - - add_buffer_attribute(buffer, g_layers_trace_attr, NET_ATTRIBUTE_STRING, layer->name), - - status = acquire_sem(g_layers.lock); - if (status != B_OK) - return status; - - status = B_ERROR; - // TODO: lookup thru a previoulsy (at each layer [un]registration time) built list of - // "above" layers of caller layer. - - // dprintf("layers_manager: send_layers_up(): layer %s (%x/%x), searching a matching upper layer...\n", - // layer->name, layer->type, layer->sub_type); - - // HACK: today, we lookup thru ALL :-( registered layers. - // In the future, such layers (de)assembly should be done at layer (un)resgistration time, as - // it never change until layers list change herself... - above = g_layers.first; - while (above) { - // dprintf("layers_manager: send_layers_up: Matching against layer %s (%x/%x) ?\n", - // above->name, above->type, above->sub_type); - - if ( above->module->process_input && - ( (above->type == g_joker_token) || (above->type == layer->sub_type) ) ) { -/* - dprintf("layers_manager: send_layers_up: handing buffer from %x/%x (%s) to %x/%x (%s)...\n", - layer->type, layer->sub_type, layer->name, - above->type, above->sub_type, above->name); -*/ - release_sem(g_layers.lock); - status = above->module->process_input(above, buffer); - if (status == B_OK) { - atomic_add(&above->use_count, 1); - // TODO: resort this layer with previous one, if required. - return status; - }; - - status = acquire_sem(g_layers.lock); - if (status != B_OK) - return status; - }; - above = above->next; - } - release_sem(g_layers.lock); - return status; -} - - -// -------------------------------------------------- -status_t send_layers_down(net_layer *layer, net_buffer *buffer) -{ - net_layer *below; - status_t status; - int i; - - if (!layer) - return B_ERROR; - - - // #### TODO: lock the layer(s) above & below hierarchy - if (!layer->layers_below) - // no layers below this one - return B_ERROR; - - add_buffer_attribute(buffer, g_layers_trace_attr, NET_ATTRIBUTE_STRING, layer->name), - - status = B_ERROR; - i = 0; - while (layer->layers_below[i]) { - below = layer->layers_below[i++]; - if (!below->module->process_output) - // this layer don't process output buffer - continue; - - status = below->module->process_output(below, buffer); - if (status == B_OK) { - atomic_add(&below->use_count, 1); - // TODO: resort this layer with previous one, if required. - return status; - }; - }; - - return status; -} - -// #pragma mark - - -// -------------------------------------------------- -static net_layer * new_layer(const char *name, const char *type, int priority, - net_layer_module_info *module, void *cookie) -{ - net_layer *layer; - - if (! g_layers_pool) - g_layers_pool = g_memory_pool->new_pool(sizeof(*layer), LAYERS_PER_POOL); - - if (! g_layers_pool) - return NULL; - - layer = (net_layer *) g_memory_pool->new_pool_node(g_layers_pool); - if (! layer) - return NULL; - - layer->name = strdup(name); - - if (type) { - char *tmp, *t, *n; - - tmp = strdup(type); - t = strtok_r(tmp, "/", &n); - layer->type = (t ? string_to_token(t) : g_joker_token); - t = strtok_r(NULL, " ", &n); - layer->sub_type = (t ? string_to_token(t) : g_joker_token); - free(tmp); - } else - layer->type = layer->sub_type = 0; - - - layer->priority = priority; - layer->module = module; - layer->cookie = cookie; - - layer->layers_above = NULL; - layer->layers_below = NULL; - - layer->attributes = NULL; - - return layer; -} - - -// -------------------------------------------------- -static status_t delete_layer(net_layer *layer) -{ - if (!layer) - return B_ERROR; - - if (! g_layers_pool) - // Uh? From where come this net_data!?! - return B_ERROR; - - if (layer->name) - free(layer->name); - - if (layer->layers_above) - free(layer->layers_above); - if (layer->layers_below) - free(layer->layers_below); - - if (layer->attributes) { - // Free layer attributes - - net_attribute *attr; - net_attribute *next_attr; - - attr = layer->attributes; - while (attr) { - next_attr = attr->next; - delete_attribute(attr, NULL); - attr = next_attr; - }; - }; - - return g_memory_pool->delete_pool_node(g_layers_pool, layer); -} - - diff --git a/src/tests/kits/net/new_stack/stack/layers_manager.h b/src/tests/kits/net/new_stack/stack/layers_manager.h deleted file mode 100644 index 9da258eaac..0000000000 --- a/src/tests/kits/net/new_stack/stack/layers_manager.h +++ /dev/null @@ -1,35 +0,0 @@ -/* layers_manager.h - * private definitions for network layers manager - */ - -#ifndef OBOS_NET_STACK_LAYERS_MANAGER_H -#define OBOS_NET_STACK_LAYERS_MANAGER_H - -#include "net_stack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern status_t start_layers_manager(void); -extern status_t stop_layers_manager(void); - -extern status_t register_layer(const char *name, const char *type, int priority, - net_layer_module_info *module, void *cookie, net_layer **layer); -extern status_t unregister_layer(net_layer *layer); -extern net_layer * find_layer(const char *name); - -extern status_t add_layer_attribute(net_layer *layer, const void *id, int type, ...); -extern status_t remove_layer_attribute(net_layer *layer, const void *id, int index); -extern status_t find_layer_attribute(net_layer *layer, const void *id, int index, - int *type, void **attribute, size_t *size); - -extern status_t send_layers_up(net_layer *me, struct net_buffer *buffer); -extern status_t send_layers_down(net_layer *me, struct net_buffer *buffer); - - -#ifdef __cplusplus -} -#endif - -#endif /* OBOS_NET_STACK_LAYERS_MANAGER_H */ diff --git a/src/tests/kits/net/new_stack/stack/stack.c b/src/tests/kits/net/new_stack/stack/stack.c deleted file mode 100644 index 6ca4d9ce26..0000000000 --- a/src/tests/kits/net/new_stack/stack/stack.c +++ /dev/null @@ -1,212 +0,0 @@ -/* stack.c */ - -/* This the heart of network stack - */ - -#include - -#include -#include - -#include "net_stack.h" -#include "memory_pool.h" -#include "atomizer.h" - -#include "stack.h" -#include "attribute.h" -#include "layers_manager.h" -#include "buffer.h" -#include "timer.h" -#include "dump.h" - -memory_pool_module_info *g_memory_pool = NULL; -atomizer_module_info *g_atomizer = NULL; -#define DEFAULT_ATOMIZER (const void *) (-1) - -static bool g_started = false; - -status_t std_ops(int32 op, ...); - -static status_t start(void); -static status_t stop(void); - - -static status_t start(void) -{ - if (g_started) - return B_OK; - - dprintf("stack: starting...\n"); - - start_buffers_service(); - start_timers_service(); - - start_layers_manager(); - - dprintf("stack: started.\n"); - g_started = true; - - return B_OK; -} - -static status_t stop(void) -{ - dprintf("stack: stopping...\n"); - - stop_layers_manager(); - - stop_timers_service(); - stop_buffers_service(); - - - dprintf("stack: stopped.\n"); - g_started = false; - - return 0; -} - - -string_token string_to_token(const char *name) -{ - status_t status; - - if (g_atomizer == NULL) { - status = get_module(B_ATOMIZER_MODULE_NAME, (module_info **) &g_atomizer); - if (status != B_OK) { - dprintf("string_to_token(%s): Can't load " B_ATOMIZER_MODULE_NAME " module!\n", name); - g_atomizer = (atomizer_module_info *) -1; - }; - }; - - if (g_atomizer == (atomizer_module_info *) -1) - return NULL; - - return g_atomizer->atomize(DEFAULT_ATOMIZER, name, true); -} - - -const char * string_for_token(string_token token) -{ - status_t status; - - if (g_atomizer == NULL) { - status = get_module(B_ATOMIZER_MODULE_NAME, (module_info **) &g_atomizer); - if (status != B_OK) { - dprintf("string_for_token(%x): Can't load " B_ATOMIZER_MODULE_NAME " module!\n", (int) token); - g_atomizer = (atomizer_module_info *) -1; - }; - }; - - if (g_atomizer == (atomizer_module_info *) -1) - return NULL; - - return g_atomizer->string_for_token(DEFAULT_ATOMIZER, token); -} - - - -// #pragma mark - - -struct net_stack_module_info nsmi = { - { - NET_STACK_MODULE_NAME, - 0, // B_KEEP_LOADED, - std_ops - }, - - // Global stack control - start, - stop, - - // String tokens - string_to_token, - string_for_token, - - // Layers handling - register_layer, - unregister_layer, - find_layer, - add_layer_attribute, - remove_layer_attribute, - find_layer_attribute, - - send_layers_up, - send_layers_down, - - // net_buffer support - new_buffer, - delete_buffer, - duplicate_buffer, - clone_buffer, - split_buffer, - - add_to_buffer, - remove_from_buffer, - - attach_buffer_free_element, - - read_buffer, - write_buffer, - - add_buffer_attribute, - remove_buffer_attribute, - find_buffer_attribute, - - dump_buffer, - - // net_buffer_queue support - new_buffer_queue, - delete_buffer_queue, - empty_buffer_queue, - enqueue_buffer, - dequeue_buffer, - - // Timers support - new_net_timer, - delete_net_timer, - start_net_timer, - cancel_net_timer, - net_timer_appointment, - - // Misc. - dump_memory -}; - -status_t std_ops(int32 op, ...) -{ - status_t status; - - switch(op) { - case B_MODULE_INIT: - dprintf("stack: B_MODULE_INIT\n"); - load_driver_symbols("stack"); - status = get_module(MEMORY_POOL_MODULE_NAME, (module_info **) &g_memory_pool); - if (status != B_OK) { - dprintf("stack: Can't load " MEMORY_POOL_MODULE_NAME " module!\n"); - return status; - }; - - // Re-publish memory_pool module api thru our - nsmi.new_pool = g_memory_pool->new_pool; - nsmi.delete_pool = g_memory_pool->delete_pool; - nsmi.new_pool_node = g_memory_pool->new_pool_node; - nsmi.delete_pool_node = g_memory_pool->delete_pool_node; - nsmi.for_each_pool_node = g_memory_pool->for_each_pool_node; - break; - - case B_MODULE_UNINIT: - dprintf("stack: B_MODULE_UNINIT\n"); - put_module(MEMORY_POOL_MODULE_NAME); - break; - - default: - return B_ERROR; - } - return B_OK; -} - -_EXPORT module_info *modules[] = { - (module_info *) &nsmi, // net_stack_module_info - NULL -}; - diff --git a/src/tests/kits/net/new_stack/stack/stack.h b/src/tests/kits/net/new_stack/stack/stack.h deleted file mode 100644 index 5714d75464..0000000000 --- a/src/tests/kits/net/new_stack/stack/stack.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef STACK_H -#define STACK_H - -#include "net_stack.h" - -extern string_token string_to_token(const char *name); -extern const char * string_for_token(string_token token); - -#endif diff --git a/src/tests/kits/net/new_stack/stack/timer.c b/src/tests/kits/net/new_stack/stack/timer.c deleted file mode 100644 index 02737b5805..0000000000 --- a/src/tests/kits/net/new_stack/stack/timer.c +++ /dev/null @@ -1,277 +0,0 @@ -/* timer.c - a small and more or less inaccurate timer for net modules. -** The registered hooks will be called in the thread of the timer. -** -** Initial version by Axel Dörfler, axeld@pinc-software.de -** -** This file may be used under the terms of the OpenBeOS License. -*/ - -#include -#include -#include -#include -#include - -#include "net_stack.h" -#include "timer.h" - -struct net_timer { - struct net_timer *next; - net_timer_func func; - void *func_cookie; - bigtime_t period; - bigtime_t until; - bool pending; -}; - -struct timers_queue { - struct net_timer *first; - sem_id lock; - sem_id wait; - int32 counter; - volatile int32 in_use; -}; - -static struct timers_queue g_timers; -static thread_id g_timers_thread = -1; - -static int32 timers_thread(void *data); - -// #pragma mark [Start/Stop Service functions] - - -// -------------------------------------------------- -status_t start_timers_service(void) -{ - memset(&g_timers, 0, sizeof(g_timers)); - - g_timers.lock = create_sem(1, "net_timers lock"); - if (g_timers.lock < B_OK) - return B_ERROR; - - g_timers.wait = create_sem(0,"net_timers wait"); - if (g_timers.wait < B_OK) - return B_ERROR; - -#ifdef _KERNEL_MODE - set_sem_owner(g_timers.lock, B_SYSTEM_TEAM); - set_sem_owner(g_timers.wait, B_SYSTEM_TEAM); -#endif - - g_timers_thread = spawn_kernel_thread(timers_thread, "timers lone runner", B_URGENT_DISPLAY_PRIORITY, &g_timers); - if (g_timers_thread < B_OK) - return g_timers_thread; - - puts("net timers service started."); - - return resume_thread(g_timers_thread); -} - - -// -------------------------------------------------- -status_t stop_timers_service(void) -{ - net_timer *nt, *next; - int32 tries = 20; - status_t status; - - delete_sem(g_timers.wait); - delete_sem(g_timers.lock); - g_timers.wait = -1; - g_timers.lock = -1; - - wait_for_thread(g_timers_thread, &status); - - // make sure the structure isn't used anymore - while (g_timers.in_use != 0 && tries-- > 0) - snooze(1000); - - // free the remaining timer entries - for (nt = g_timers.first; nt; nt = next) { - next = nt->next; - free(nt); - } - - puts("net timers service stopped."); - - return B_OK; -} - - -// #pragma mark [Public functions] - -// -------------------------------------------------- -net_timer * new_net_timer(void) -{ - return NULL; -} - - -// -------------------------------------------------- -status_t delete_net_timer(net_timer *nt) -{ - return B_ERROR; -} - - -// -------------------------------------------------- -status_t start_net_timer(net_timer *nt, net_timer_func func, void *cookie, bigtime_t period) -{ - return B_ERROR; -} - - -// -------------------------------------------------- -status_t cancel_net_timer(net_timer *nt) -{ - return B_ERROR; -} - - -// -------------------------------------------------- -status_t net_timer_appointment(net_timer *nt, bigtime_t *period, bigtime_t *when) -{ - return 0; -} - -// #pragma mark - - -// -------------------------------------------------- -static int32 timers_thread(void *data) -{ - struct timers_queue *timers = (struct timers_queue *) data; - status_t status = B_OK; - - do { - bigtime_t timeout = B_INFINITE_TIMEOUT; - net_timer *nt; - - // get access to the info structure - if (status == B_TIMED_OUT || status == B_OK) { - if (acquire_sem(timers->lock) == B_OK) { - for (nt = timers->first; nt; nt = nt->next) { - // new entry? - if (nt->until == -1) - nt->until = system_time() + nt->period; - - // execute timer? - if (nt->until < system_time()) { - nt->until += nt->period; - nt->func(nt, nt->func_cookie); - } - - // calculate new timeout - if (nt->until < timeout) - timeout = nt->until; - } - - release_sem(timers->lock); - } - } - - status = acquire_sem_etc(timers->wait, 1, B_ABSOLUTE_TIMEOUT, timeout); - // the wait sem normally can't be acquired, so we - // have to look at the status value the call returns: - // - // B_OK - someone wanted to notify us - // B_TIMED_OUT - look for timers to be executed - // B_BAD_SEM_ID - our sem got deleted - - } while (status != B_BAD_SEM_ID); - - return 0; -} - -#if 0 - - - -net_timer_id -net_add_timer(net_timer_hook hook,void *data,bigtime_t interval) -{ - struct timer_entry *te; - status_t status; - - if (interval < 100) - return B_BAD_VALUE; - - atomic_add(&gTimerInfo.ti_inUse,1); - - // get access to the timer info structure - status = acquire_sem(gTimerInfo.ti_lock); - if (status < B_OK) { - atomic_add(&gTimerInfo.ti_inUse,-1); - return status; - } - - te = (struct timer_entry *)malloc(sizeof(struct timer_entry)); - if (te == NULL) { - atomic_add(&gTimerInfo.ti_inUse,-1); - release_sem(gTimerInfo.ti_lock); - return B_NO_MEMORY; - } - - te->te_hook = hook; - te->te_data = data; - te->te_interval = interval; - te->te_until = -1; - te->te_id = ++gTimerInfo.ti_counter; - - // add the new entry - te->te_next = gTimerInfo.ti_first; - gTimerInfo.ti_first = te; - - atomic_add(&gTimerInfo.ti_inUse,-1); - release_sem(gTimerInfo.ti_lock); - - // notify timer about the change - release_sem(gTimerInfo.ti_wait); - - return te->te_id; -} - - -status_t -net_remove_timer(net_timer_id id) -{ - struct timer_entry *te,*last; - status_t status; - - if (id <= B_OK) - return B_BAD_VALUE; - - atomic_add(&gTimerInfo.ti_inUse,1); - - // get access to the timer info structure - status = acquire_sem(gTimerInfo.ti_lock); - if (status < B_OK) { - atomic_add(&gTimerInfo.ti_inUse,-1); - return status; - } - - // search the list for the right timer - - // little hack that relies on ti_first being on the same position - // in the structure as te_next - last = (struct timer_entry *)&gTimerInfo; - for (te = gTimerInfo.ti_first;te;te = te->te_next) { - if (te->te_id == id) { - last->te_next = te->te_next; - free(te); - break; - } - last = te; - } - atomic_add(&gTimerInfo.ti_inUse,-1); - release_sem(gTimerInfo.ti_lock); - - if (te == NULL) - return B_ENTRY_NOT_FOUND; - - // notify timer about the change - release_sem(gTimerInfo.ti_wait); - - return B_OK; -} - -#endif \ No newline at end of file diff --git a/src/tests/kits/net/new_stack/stack/timer.h b/src/tests/kits/net/new_stack/stack/timer.h deleted file mode 100644 index 984f8784e0..0000000000 --- a/src/tests/kits/net/new_stack/stack/timer.h +++ /dev/null @@ -1,37 +0,0 @@ -/* timer.h - * private definitions for network timers support - */ - -#ifndef OBOS_NET_STACK_TIMER_H -#define OBOS_NET_STACK_TIMER_H - -/* timer.h - a small and more or less inaccurate timer for net modules. -** The registered hooks will be called in the thread of the timer. -** -** Initial version by Axel Dörfler, axeld@pinc-software.de -** -** This file may be used under the terms of the OpenBeOS License. -*/ - -#include - -#include "net_stack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern status_t start_timers_service(void); -extern status_t stop_timers_service(void); - -extern net_timer * new_net_timer(void); -extern status_t delete_net_timer(net_timer *nt); -extern status_t start_net_timer(net_timer *nt, net_timer_func hook, void *cookie, bigtime_t period); -extern status_t cancel_net_timer(net_timer *nt); -extern status_t net_timer_appointment(net_timer *nt, bigtime_t *period, bigtime_t *when); - -#ifdef __cplusplus -} -#endif - -#endif /* OBOS_NET_STACK_TIMER_H */ diff --git a/src/tests/kits/net/new_stack/userland_ipc.c b/src/tests/kits/net/new_stack/userland_ipc.c deleted file mode 100644 index 2253a0ffec..0000000000 --- a/src/tests/kits/net/new_stack/userland_ipc.c +++ /dev/null @@ -1,554 +0,0 @@ -/* userland_ipc - Communication between the network driver -** and the userland stack. -** -** Initial version by Axel Dörfler, axeld@pinc-software.de -** This file may be used under the terms of the OpenBeOS License. -*/ - - -#include "userland_ipc.h" - -#include "sys/socket.h" -#include "net_misc.h" -#include "core_module.h" -#include "net_module.h" -#include "sys/sockio.h" - -#include -#include -#include - - -extern struct core_module_info *core; - -// installs a main() -//#define COMMUNICATION_TEST - -#define NUM_COMMANDS 32 -#define CONNECTION_BUFFER_SIZE (65536 + 4096 - CONNECTION_COMMAND_SIZE) - -#define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1)) - -struct socket; /* forward declaration */ - -typedef struct { - port_id localPort,port; - area_id area; - struct socket * socket; - - uint8 *buffer; - net_command *commands; - sem_id commandSemaphore; - - int32 openFlags; - - thread_id runner; - - // for socket select events support - port_id socket_event_port; - void * notify_cookie; -} connection_cookie; - - -port_id gStackPort = -1; -thread_id gConnectionOpener = -1; - -// prototypes -static int32 connection_runner(void *_cookie); -static status_t init_connection(net_connection *connection, connection_cookie **_cookie); -static void shutdown_connection(connection_cookie *cookie); - - -static void -delete_cloned_areas(net_area_info *area) -{ - int32 i; - for (i = 0;i < MAX_NET_AREAS;i++) { - if (area[i].id == 0) - continue; - - delete_area(area[i].id); - } -} - - -static status_t -clone_command_areas(net_area_info *localArea,net_command *command) -{ - int32 i; - - memset(localArea,0,sizeof(net_area_info) * MAX_NET_AREAS); - - for (i = 0;i < MAX_NET_AREAS;i++) { - if (command->area[i].id <= 0) - continue; - - localArea[i].id = clone_area("net connection",(void **)&localArea[i].offset,B_ANY_ADDRESS, - B_READ_AREA | B_WRITE_AREA,command->area[i].id); - if (localArea[i].id < B_OK) - return localArea[i].id; - } - return B_OK; -} - - -static uint8 * -convert_address(net_area_info *fromArea,net_area_info *toArea,uint8 *data) -{ - if (data == NULL) - return NULL; - - if (data < fromArea->offset) { - printf("could not translate address: %p\n",data); - return data; - } - - return data - fromArea->offset + toArea->offset; -} - - -static inline void * -convert_to_local(net_area_info *foreignArea,net_area_info *localArea,void *data) -{ - return convert_address(foreignArea,localArea,data); -} - - -static void * -convert_to_foreign(net_area_info *foreignArea,net_area_info *localArea,void *data) -{ - return convert_address(localArea,foreignArea,data); -} - - -static void -on_socket_event(void * socket, uint32 event, void * cookie) -{ - connection_cookie * cc = (connection_cookie *) cookie; - struct socket_event_data sed; - status_t status; - - if (!cc) - return; - - if (cc->socket != socket) { - printf("on_socket_event(%p, %ld, %p): socket is higly suspect! Aborting.\n", socket, event, cookie); - return; - } - - printf("on_socket_event(%p, %ld, %p)\n", socket, event, cookie); - - sed.event = event; - sed.cookie = cc->notify_cookie; - - // TODO: don't block here => write_port_etc() ? - status = write_port(cc->socket_event_port, NET_STACK_SOCKET_EVENT_NOTIFICATION, - &sed, sizeof(sed)); - if (status != B_OK) - printf("write_port(NET_STACK_SOCKET_EVENT_NOTIFICATION) failure: %s\n", - strerror(status)); - return; -} - - - -static int32 -connection_runner(void *_cookie) -{ - connection_cookie *cookie = (connection_cookie *)_cookie; - bool run = true; - - while (run) { - net_area_info area[MAX_NET_AREAS]; - net_command *command; - status_t status = B_OK; - uint8 *data; - int32 index; - ssize_t bytes = read_port(cookie->localPort,&index,NULL,0); - if (bytes < B_OK) - break; - - if (index >= NUM_COMMANDS || index < 0) { - printf("got bad command index: %lx\n",index); - continue; - } - command = cookie->commands + index; - if (clone_command_areas(area,command) < B_OK) { - printf("could not clone command areas!\n"); - continue; - } - - data = convert_to_local(&command->area[0],&area[0],command->data); - printf("command %lx (index = %ld), buffer = %p, length = %ld, result = %ld\n",command->op,index,data,command->length,command->result); - - switch (command->op) { - case NET_STACK_OPEN: - { - struct int_args *args = (struct int_args *)data; - cookie->openFlags = args->value; - printf("opening socket, mode = %lx!\n",cookie->openFlags); - break; - } - case NET_STACK_CLOSE: - printf("closing socket...\n"); - run = false; - break; - - case NET_STACK_SOCKET: - { - struct socket_args *args = (struct socket_args *)data; - - printf("open a socket... family = %d, type = %d, proto = %d\n",args->family,args->type,args->proto); - status = core->socket_init(&cookie->socket); - if (status == 0) - status = core->socket_create(cookie->socket, args->family, args->type, args->proto); - break; - } - case NET_STACK_GETSOCKOPT: - case NET_STACK_SETSOCKOPT: - { - struct sockopt_args *sockopt = (struct sockopt_args *)data; - - if (command->op == NET_STACK_GETSOCKOPT) { - status = core->socket_getsockopt(cookie->socket,sockopt->level,sockopt->option, - convert_to_local(&command->area[1],&area[1],sockopt->optval), - (size_t *)&sockopt->optlen); - } else { - status = core->socket_setsockopt(cookie->socket,sockopt->level,sockopt->option, - (const void *)convert_to_local(&command->area[1],&area[1],sockopt->optval), - sockopt->optlen); - } - break; - } - case NET_STACK_CONNECT: - case NET_STACK_BIND: - case NET_STACK_GETSOCKNAME: - case NET_STACK_GETPEERNAME: - { - struct sockaddr_args *args = (struct sockaddr_args *)data; - caddr_t addr = (caddr_t)convert_to_local(&command->area[1],&area[1],args->addr); - - switch (command->op) { - case NET_STACK_CONNECT: - status = core->socket_connect(cookie->socket,addr,args->addrlen); - break; - case NET_STACK_BIND: - status = core->socket_bind(cookie->socket,addr,args->addrlen); - break; - case NET_STACK_GETSOCKNAME: - status = core->socket_getsockname(cookie->socket,(struct sockaddr *)addr,&args->addrlen); - break; - case NET_STACK_GETPEERNAME: - status = core->socket_getpeername(cookie->socket,(struct sockaddr *)addr,&args->addrlen); - break; - } - break; - } - case NET_STACK_LISTEN: - status = core->socket_listen(cookie->socket,((struct int_args *)data)->value); - break; - - case NET_STACK_GET_COOKIE: - /* this is needed by accept() call, to be able to pass back - * in NET_STACK_ACCEPT opcode the cookie of the filedescriptor to - * use for the new accepted socket - */ - *((void **)data) = cookie; - break; - - case NET_STACK_ACCEPT: - { - struct accept_args *args = (struct accept_args *)data; - connection_cookie *otherCookie = (connection_cookie *)args->cookie; - status = core->socket_accept(cookie->socket,&otherCookie->socket, - convert_to_local(&command->area[1],&area[1],args->addr), - &args->addrlen); - } - case NET_STACK_SEND: - { - struct data_xfer_args *args = (struct data_xfer_args *)data; - struct iovec iov; - int flags = 0; - - iov.iov_base = convert_to_local(&command->area[1],&area[1],args->data); - iov.iov_len = args->datalen; - - status = core->socket_writev(cookie->socket,&iov,flags); - break; - } - case NET_STACK_RECV: - { - struct data_xfer_args *args = (struct data_xfer_args *)data; - struct iovec iov; - int flags = 0; - - iov.iov_base = convert_to_local(&command->area[1],&area[1],args->data); - iov.iov_len = args->datalen; - - /* flags gets ignored here... */ - status = core->socket_readv(cookie->socket,&iov,&flags); - break; - } - case NET_STACK_RECVFROM: - { - struct msghdr *msg = (struct msghdr *)data; - int received; - - msg->msg_name = convert_to_local(&command->area[1],&area[1],msg->msg_name); - msg->msg_iov = convert_to_local(&command->area[2],&area[2],msg->msg_iov); - msg->msg_control = convert_to_local(&command->area[3],&area[3],msg->msg_control); - - status = core->socket_recv(cookie->socket, msg, (caddr_t)&msg->msg_namelen,&received); - if (status == 0) - status = received; - - msg->msg_name = convert_to_foreign(&command->area[1],&area[1],msg->msg_name); - msg->msg_iov = convert_to_foreign(&command->area[2],&area[2],msg->msg_iov); - msg->msg_control = convert_to_foreign(&command->area[3],&area[3],msg->msg_control); - break; - } - case NET_STACK_SENDTO: - { - struct msghdr *msg = (struct msghdr *)data; - int sent; - - msg->msg_name = convert_to_local(&command->area[1],&area[1],msg->msg_name); - msg->msg_iov = convert_to_local(&command->area[2],&area[2],msg->msg_iov); - msg->msg_control = convert_to_local(&command->area[3],&area[3],msg->msg_control); - - status = core->socket_send(cookie->socket,msg,msg->msg_flags,&sent); - if (status == 0) - status = sent; - - msg->msg_name = convert_to_foreign(&command->area[1],&area[1],msg->msg_name); - msg->msg_iov = convert_to_foreign(&command->area[2],&area[2],msg->msg_iov); - msg->msg_control = convert_to_foreign(&command->area[3],&area[3],msg->msg_control); - break; - } - - case NET_STACK_NOTIFY_SOCKET_EVENT: - { - struct notify_socket_event_args *args = (struct notify_socket_event_args *)data; - - cookie->socket_event_port = args->notify_port; - cookie->notify_cookie = args->cookie; - - if (cookie->socket_event_port != -1) - // start notify socket event - status = core->socket_set_event_callback(cookie->socket, on_socket_event, cookie, 0); - else - // stop notify socket event - status = core->socket_set_event_callback(cookie->socket, NULL, NULL, 0); - break; - } - - case NET_STACK_SYSCTL: - { - struct sysctl_args *args = (struct sysctl_args *)data; - - status = core->net_sysctl(convert_to_local(&command->area[1],&area[1],args->name), - args->namelen,convert_to_local(&command->area[2],&area[2],args->oldp), - convert_to_local(&command->area[3],&area[3],args->oldlenp), - convert_to_local(&command->area[4],&area[4],args->newp), - args->newlen); - break; - } - - case NET_STACK_STOP: - core->stop(); - break; - - case B_SET_BLOCKING_IO: - cookie->openFlags &= ~O_NONBLOCK; - break; - - case B_SET_NONBLOCKING_IO: - cookie->openFlags |= O_NONBLOCK; - break; - - case OSIOCGIFCONF: - case SIOCGIFCONF: - { - struct ifconf *ifc = (struct ifconf *)data; - ifc->ifc_buf = convert_to_local(&command->area[1],&area[1],ifc->ifc_buf); - - status = core->socket_ioctl(cookie->socket,command->op,(char *)data); - - ifc->ifc_buf = convert_to_foreign(&command->area[1],&area[1],ifc->ifc_buf); - break; - } - - default: - status = core->socket_ioctl(cookie->socket,command->op,(char *)data); - break; - } - // mark the command as done - command->result = status; - command->op = 0; - delete_cloned_areas(area); - - // notify the command pipeline that we're done with the command - release_sem(cookie->commandSemaphore); - } - - cookie->runner = -1; - shutdown_connection(cookie); - - return 0; -} - - -static status_t -init_connection(net_connection *connection,connection_cookie **_cookie) -{ - connection_cookie *cookie; - net_command *commands; - - cookie = (connection_cookie *)malloc(sizeof(connection_cookie)); - if (cookie == NULL) { - fprintf(stderr,"couldn't allocate memory for cookie.\n"); - return B_NO_MEMORY; - } - - connection->area = create_area("net connection",(void *)&commands,B_ANY_ADDRESS, - CONNECTION_BUFFER_SIZE + CONNECTION_COMMAND_SIZE, - B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); - if (connection->area < B_OK) { - fprintf(stderr,"couldn't create area: %s.\n",strerror(connection->area)); - free(cookie); - return connection->area; - } - memset(commands,0,NUM_COMMANDS * sizeof(net_command)); - - connection->port = create_port(CONNECTION_QUEUE_LENGTH,"net stack connection"); - if (connection->port < B_OK) { - fprintf(stderr,"couldn't create port: %s.\n",strerror(connection->port)); - delete_area(connection->area); - free(cookie); - return connection->port; - } - - connection->commandSemaphore = create_sem(0,"net command queue"); - if (connection->commandSemaphore < B_OK) { - fprintf(stderr,"couldn't create semaphore: %s.\n",strerror(connection->commandSemaphore)); - delete_area(connection->area); - delete_port(connection->port); - free(cookie); - return connection->commandSemaphore; - } - - cookie->runner = spawn_thread(connection_runner,"connection runner",B_NORMAL_PRIORITY,cookie); - if (cookie->runner < B_OK) { - fprintf(stderr,"couldn't create thread: %s.\n",strerror(cookie->runner)); - delete_sem(connection->commandSemaphore); - delete_area(connection->area); - delete_port(connection->port); - free(cookie); - return B_ERROR; - } - - connection->numCommands = NUM_COMMANDS; - connection->bufferSize = CONNECTION_BUFFER_SIZE; - - // setup connection cookie - cookie->area = connection->area; - cookie->commands = commands; - cookie->buffer = (uint8 *)commands + CONNECTION_COMMAND_SIZE; - cookie->commandSemaphore = connection->commandSemaphore; - cookie->localPort = connection->port; - cookie->openFlags = 0; - - cookie->socket_event_port = -1; - cookie->notify_cookie = NULL; - - resume_thread(cookie->runner); - - *_cookie = cookie; - return B_OK; -} - - -static void -shutdown_connection(connection_cookie *cookie) -{ - printf("free cookie: %p\n",cookie); - kill_thread(cookie->runner); - - delete_port(cookie->localPort); - delete_sem(cookie->commandSemaphore); - delete_area(cookie->area); - - free(cookie); -} - - -static int32 -connection_opener(void *_unused) -{ - while(true) { - port_id port; - int32 msg; - ssize_t bytes = read_port(gStackPort,&msg,&port,sizeof(port_id)); - if (bytes < B_OK) - return bytes; - - if (msg == NET_STACK_NEW_CONNECTION) { - net_connection connection; - connection_cookie *cookie; - - printf("incoming connection...\n"); - if (init_connection(&connection,&cookie) == B_OK) - write_port(port,NET_STACK_NEW_CONNECTION,&connection,sizeof(net_connection)); - } else - fprintf(stderr,"connection_opener: received unknown command: %lx (expected = %lx)\n",msg,(int32)NET_STACK_NEW_CONNECTION); - } - return 0; -} - - -status_t -init_userland_ipc(void) -{ - gStackPort = create_port(CONNECTION_QUEUE_LENGTH,NET_STACK_PORTNAME); - if (gStackPort < B_OK) - return gStackPort; - - gConnectionOpener = spawn_thread(connection_opener,"connection opener",B_NORMAL_PRIORITY,NULL); - if (resume_thread(gConnectionOpener) < B_OK) { - delete_port(gStackPort); - if (gConnectionOpener >= B_OK) { - kill_thread(gConnectionOpener); - return B_BAD_THREAD_STATE; - } - return gConnectionOpener; - } - - return B_OK; -} - - -void -shutdown_userland_ipc(void) -{ - delete_port(gStackPort); - kill_thread(gConnectionOpener); -} - - -#ifdef COMMUNICATION_TEST -int -main(void) -{ - char buffer[8]; - - if (init_userland_ipc() < B_OK) - return -1; - - puts("Userland_ipc - test is running. Press to quit."); - fgets(buffer,sizeof(buffer),stdin); - - shutdown_userland_ipc(); - - return 0; -} -#endif /* COMMUNICATION_TEST */ diff --git a/src/tests/kits/net/new_stack/userland_ipc.h b/src/tests/kits/net/new_stack/userland_ipc.h deleted file mode 100644 index c3980481c9..0000000000 --- a/src/tests/kits/net/new_stack/userland_ipc.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef USERLAND_IPC_H -#define USERLAND_IPC_H -/* userland_ipc - Communication between the network driver -** and the userland stack. -** -** Initial version by Axel Dörfler, axeld@pinc-software.de -** This file may be used under the terms of the OpenBeOS License. -*/ - - -#include -#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 5 - -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; - - 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 */ diff --git a/src/tests/kits/net/new_stack/userland_modules.cpp b/src/tests/kits/net/new_stack/userland_modules.cpp deleted file mode 100644 index 52647678c8..0000000000 --- a/src/tests/kits/net/new_stack/userland_modules.cpp +++ /dev/null @@ -1,869 +0,0 @@ -/* Userland modules emulation support -*/ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define ASSERT(condition) if (!(condition)) { debugger("Assertion failed!"); } - -typedef enum { - MODULE_LOADED = 0, - MODULE_INITING, - MODULE_READY, - MODULE_UNINITING, - MODULE_ERROR -} module_state; - -typedef struct module { - struct module * next; - uint32 id; - char * name; - module_info * info; - struct module_addon * addon; // the module addon this module live in - // if NULL, builtin module addon - int32 ref_count; // reference count of get_module() made on this module - bool keep_loaded; - module_state state; -} module; - -typedef struct module_addon { - struct module_addon * next; - int32 ref_count; // reference count of get_module() made using this addon - bool keep_loaded; - char * path; - image_id addon_image; // if -1, not loaded in memory currently - module_info ** infos; // valid only when addon_image != -1 -} module_addon; - -typedef struct module_list_cookie { - char * prefix; - char * search_paths; - char * search_path; - char * next_path_token; - BList * dir_stack; - module_addon * ma; // current module addon looked up - module_info ** mi; // current module addon module info -} module_list_cookie; - -#define LOCK_MODULES acquire_sem(g_modules_lock) -#define UNLOCK_MODULES release_sem(g_modules_lock) - -// local prototypes -// ------------------ - -static module * search_module(const char * name); -static status_t init_module(module * m); -static status_t uninit_module(module * m); -static module * find_loaded_module_by_name(const char * name); -static module * find_loaded_module_by_id(uint32 id); - -static module_addon * load_module_addon(const char * path); -static status_t unload_module_addon(module_addon * ma); - -// globals -// ------------------ - -static sem_id g_modules_lock = -1; // One lock for rule them all, etc... -static module * g_modules = NULL; -static module_addon * g_module_addons = NULL; -static int32 g_next_module_id = 1; - - -// Public routines -// --------------- - -extern "C" { - -_EXPORT status_t get_module(const char * name, module_info ** mi) -{ - status_t status; - module * m; - - // printf("get_module(%s)\n", name); - - m = find_loaded_module_by_name(name); - if (!m) - m = search_module(name); - - if (!m) - return B_NAME_NOT_FOUND; - - *mi = m->info; - - status = B_OK; - - if (m->addon) // built-in modules don't comes from addon... - atomic_add(&m->addon->ref_count, 1); - - if (atomic_add(&m->ref_count, 1) == 0) { - // first time we reference this module, so let's init it: - status = init_module(m); - if (status != B_OK) { - printf("Failed to init module %s: %s.\n", m->name, strerror(status)); - unload_module_addon(m->addon); // unload the module addon... - }; - }; - - return status; -} - -_EXPORT status_t put_module(const char * name) -{ - module * m; - - // printf("put_module(%s)\n", name); - - m = find_loaded_module_by_name(name); - if (!m) - // Hum??? Sorry, this module name was never get_module()'d - return B_NAME_NOT_FOUND; - - if (atomic_add(&m->ref_count, -1) <= 1) - // this module is no more used... - uninit_module(m); - - if (!m->addon) - // built-in modules are module addon less... - return B_OK; - - if (atomic_add(&m->addon->ref_count, -1) > 1) - // Still other module(s) using this module addon - return B_OK; - - // okay, this module addon is no more used - // let's free up some memory - return unload_module_addon(m->addon); -} - - -_EXPORT status_t get_next_loaded_module_name(uint32 *cookie, char *buf, size_t *bufsize) -{ - module * m; - status_t status; - - if (buf == NULL && bufsize == NULL) - return B_BAD_VALUE; - - LOCK_MODULES; - - if (*cookie == 0) - // first call expected value - m = g_modules; - else { - // find last loaded module returned, and seek to next one - m = (module *) find_loaded_module_by_id((int) *cookie); - if (m) - m = m->next; - }; - - // find next loaded module - while (m) { - if (m->ref_count) - break; - m = m->next; - }; - - status = B_OK; - if (m) { - ASSERT(m->info); - if (buf != NULL) - strncpy(buf, m->info->name, *bufsize); - else - *bufsize = strlen(m->info->name + 1); - *cookie = m->id; - } else - status = B_BAD_INDEX; - - UNLOCK_MODULES; - - return status; -} - - -_EXPORT void * open_module_list(const char *prefix) -{ - module_list_cookie * mlc; - char * addon_path; - - if (prefix == NULL) - return NULL; - - mlc = (module_list_cookie *) malloc(sizeof(*mlc)); - mlc->prefix = strdup(prefix); - - addon_path = getenv("ADDON_PATH"); - mlc->search_paths = (addon_path ? strdup(addon_path) : NULL); - mlc->search_path = strtok_r(mlc->search_paths, ":", &mlc->next_path_token); - mlc->dir_stack = new BList(); - - mlc->ma = NULL; - mlc->mi = NULL; - - return mlc; -} - - -_EXPORT status_t read_next_module_name(void *cookie, char *buf, size_t *bufsize) -{ - module_list_cookie * mlc = (module_list_cookie *) cookie; - - if (!bufsize) - return B_BAD_VALUE; - - if (!mlc) - return B_BAD_VALUE; - - /* Okay, take some time to understand how this function works! - Basicly, we iterate thru: - - each searchable add-ons path root - - each (sub-)directory under the current add-ons path root - - each module add-on file in the current (sub-)directory - - each module name published by current module add-on - - As the iteration involve sub-directory walks, we use recursive calls. - Sorry if this code sounds too complex... - */ - - if (mlc->ma && mlc->mi) { - // we have a module addon still loaded from a last call - // so keep looking at his exported module names list - while (*mlc->mi) { - module_info * mi = *mlc->mi; - mlc->mi++; - if(strstr(mi->name, mlc->prefix)) { - // We find a matching module name. At least. Yeah!!! - if (buf) strncpy(buf, mi->name, *bufsize); - *bufsize = strlen(mi->name); - return B_OK; - }; - }; - - // We've iterate all module names of this module addon. Find another one... - atomic_add(&mlc->ma->ref_count, -1); - unload_module_addon(mlc->ma); - mlc->ma = NULL; - mlc->mi = NULL; - }; - - // Iterate all searchable add-ons paths - while (mlc->search_path) { - BDirectory * dir; - BEntry entry; - BPath path; - status_t status; - - // Get current directory - dir = (BDirectory *) mlc->dir_stack->LastItem(); - if (!dir) { - // find add-ons root directory in this search path - if (strncmp(mlc->search_path, "%A/", 3) == 0) { - // resolve "%A/..." path - app_info ai; - - be_app->GetAppInfo(&ai); - entry.SetTo(&ai.ref); - entry.GetPath(&path); - path.GetParent(&path); - path.Append(mlc->search_path + 3); - } else { - path.SetTo(mlc->search_path); - }; - - // We look *only* under prefix-matching sub-path - path.Append(mlc->prefix); - - // printf("Looking module(s) in %s/%s...\n", mlc->search_path, mlc->prefix); - - dir = new BDirectory(path.Path()); - if (dir) - mlc->dir_stack->AddItem(dir); - }; - - // Iterate current directory content - if (dir) { - while (dir->GetNextEntry(&entry) == B_OK) { - entry.GetPath(&path); - // printf(" %s ?\n", path.Path()); - - if (entry.IsDirectory()) { - BDirectory * subdir; - // push this directory on dir_stack - subdir = new BDirectory(path.Path()); - if (!subdir) - continue; - - mlc->dir_stack->AddItem(subdir); - // recursivly search this sub-directory - return read_next_module_name(cookie, buf, bufsize); - }; - - if (entry.IsFile() || entry.IsSymLink()) { - mlc->ma = load_module_addon(path.Path()); - if (!mlc->ma) - // Oh-oh, not a loadable module addon!? - // WTF it's doing there?!? - continue; - - atomic_add(&mlc->ma->ref_count, 1); - // call ourself to enter the module names list iteration at - // function begining code... - mlc->mi = mlc->ma->infos; - return read_next_module_name(cookie, buf, bufsize); - }; - }; - - // We walk thru all this directory content, go back to parent - status = mlc->dir_stack->RemoveItem(dir); - delete dir; - }; - - if (!mlc->dir_stack->IsEmpty()) - continue; - - // We walk thru all this search path content, next now - mlc->search_path = strtok_r(NULL, ":", &mlc->next_path_token); - }; - - // Module(s) list search done, ending... - return B_ERROR; -} - - -_EXPORT status_t close_module_list(void *cookie) -{ - module_list_cookie * mlc = (module_list_cookie *) cookie; - BDirectory * dir; - - ASSERT(mlc); - ASSERT(mlc->prefix); - - if (mlc->ma) { - atomic_add(&mlc->ma->ref_count, -1); - unload_module_addon(mlc->ma); - }; - - while((dir = (BDirectory *) mlc->dir_stack->FirstItem())) { - mlc->dir_stack->RemoveItem(dir); - delete dir; - }; - - delete mlc->dir_stack; - - free(mlc->search_paths); - free(mlc->prefix); - free(mlc); - - return B_ERROR; -} - -// #pragma mark - -// Some KernelExport.h support from userland - -_EXPORT void dprintf(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); -} - - -_EXPORT void kprintf(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); -} - - -_EXPORT status_t load_driver_symbols(const char *driver_name) -{ - // Userland debugger will extract symbols itself... - return B_OK; -} - - -_EXPORT thread_id spawn_kernel_thread(thread_entry func, const char *name, long priority, void *arg) -{ - return spawn_thread(func, name, priority, arg); -} - - - -_EXPORT int send_signal_etc(pid_t thid, uint sig, uint32 flags) -{ - return send_signal(thid, sig); -} - - -} // extern "C" - - -// #pragma mark - -// Private routines - -static module_addon * load_module_addon(const char * path) -{ - module_addon * ma; - image_id addon_id; - module_info ** mi; - status_t status; - - ASSERT(path); - - addon_id = load_add_on(path); - if (addon_id < 0) { - printf("Failed to load %s addon: %s.\n", path, strerror(addon_id)); - return NULL; - }; - - // printf("Addon %s loaded.\n", path); - - ma = NULL; - - status = get_image_symbol(addon_id, "modules", B_SYMBOL_TYPE_DATA, (void **) &mi); - if (status != B_OK) { - // No "modules" symbol found in this addon - printf("Symbol \"modules\" not found in %s addon: not a module addon!\n", path); - goto error; - }; - - ma = (module_addon *) malloc(sizeof(*ma)); - if (!ma) - // Gasp: not enough memory! - goto error; - - LOCK_MODULES; - - ma->ref_count = 0; - ma->keep_loaded = false; - ma->path = strdup(path); - ma->addon_image = addon_id; - ma->infos = mi; - - while(*mi) { - module * m; - - m = (module *) malloc(sizeof(*m)); - if (!m) - // Gasp, again: not enough memory! - goto error; - - m->ref_count = 0; - m->id = atomic_add(&g_next_module_id, 1); - m->info = (*mi); - m->name = strdup(m->info->name); - m->addon = ma; - m->keep_loaded = (m->info->flags & B_KEEP_LOADED) ? true : false; - - m->state = MODULE_LOADED; - - m->next = g_modules; - g_modules = m; - - mi++; - }; - - // add this module addon to the list - ma->next = g_module_addons; - g_module_addons = ma; - - UNLOCK_MODULES; - - return ma; - -error: - printf("Error while load_module_addon(%s)\n", path); - - if (ma) { - // remove any appended modules by this module addon until we got error... - module * prev; - module * m; - - prev = NULL; - m = g_modules; - while (m) { - if (m->addon == ma) { - module * tmp = m; - - m = tmp->next; - - if (prev) - prev->next = tmp->next; - else - g_modules = tmp->next; - - if (tmp->name) - free(tmp->name); - free(tmp); - continue; - }; - - prev = m; - m = m->next; - }; - - - UNLOCK_MODULES; - - if (ma->path) - free(ma->path); - free(ma); - }; - - unload_add_on(addon_id); - // printf("Addon %s unloaded.\n", path); - return NULL; -} - -static status_t unload_module_addon(module_addon * ma) -{ - module * m; - module * prev; - status_t status; - - if (!ma) - // built-in modules are addon-less, so nothing to do... - return B_OK; - - if (ma->keep_loaded) { - printf("B_KEEP_LOADED flag set for %s module addon. Will be *never* unloaded!\n", - ma->path); - return B_OK; - }; - - if (ma->ref_count) - // still someone needing this module addon, it seems? - return B_OK; - - if (ma->addon_image < 0) - // built-in addon, it seems... - return B_OK; - - status = unload_add_on(ma->addon_image); - if (status != B_OK) { - printf("Failed to unload %s addon: %s.\n", ma->path, strerror(status)); - return status; - }; - // printf("Addon %s unloaded.\n", ma->path); - - LOCK_MODULES; - - // remove the modules coming from this module addon from g_modules list - prev = NULL; - m = g_modules; - while (m) { - if (m->addon == ma) { - module * tmp = m; - - m = tmp->next; - - if (prev) - prev->next = tmp->next; - else - g_modules = tmp->next; - - if (tmp->name) - free(tmp->name); - free(tmp); - continue; - }; - - prev = m; - m = m->next; - }; - - // remove the module addon from g_module_addons list: - if (g_module_addons == ma) - g_module_addons = ma->next; - else { - module_addon * tmp; - tmp = g_module_addons; - while (tmp && tmp->next != ma) - tmp = tmp->next; - - ASSERT(tmp); - tmp->next = ma->next; - }; - - if (ma->path) - free(ma->path); - free(ma); - - UNLOCK_MODULES; - - return B_OK; -} - - -static module * search_module(const char * name) -{ - BPath path; - BPath addons_path; - BEntry entry; - module * found_module; - char * search_paths; - char * search_path; - char * next_path_token; - - // printf("search_module(%s):\n", name); - - search_paths = getenv("ADDON_PATH"); - if (!search_paths) - // Nowhere to search addons!!! - return NULL; - - search_paths = strdup(search_paths); - search_path = strtok_r(search_paths, ":", &next_path_token); - - found_module = NULL; - while (search_path && found_module == NULL) { - if (strncmp(search_path, "%A/", 3) == 0) { - // compute "%A/..." path - app_info ai; - - be_app->GetAppInfo(&ai); - entry.SetTo(&ai.ref); - entry.GetPath(&addons_path); - addons_path.GetParent(&addons_path); - addons_path.Append(search_path + 3); - } else { - addons_path.SetTo(search_path); - }; - - // printf("Looking into %s\n", search_path); - - path.SetTo(addons_path.Path()); - path.Append(name); - - while(path != addons_path) { - // printf(" %s ?\n", path.Path()); - entry.SetTo(path.Path()); - if (entry.IsFile() || entry.IsSymLink()) { - module_addon * ma; - - // try to load the module addon - ma = load_module_addon(path.Path()); - if (ma) { - found_module = find_loaded_module_by_name(name); - if (found_module) - break; - - unload_module_addon(ma); - }; // if (ma) - }; // if (entry.IsFile() || entry.IsSymLink()) - - // okay, remove the current path leaf and try again... - path.GetParent(&path); - }; - - search_path = strtok_r(NULL, ":", &next_path_token); - }; - - free(search_paths); - -/* - if (found_module) - printf(" Found it in %s addon module!\n", - found_module->addon ? found_module->addon->path : "BUILTIN"); -*/ - - return found_module; -} - - -static status_t init_module(module * m) -{ - status_t status; - - ASSERT(m); - - switch (m->state) { - case MODULE_LOADED: - m->state = MODULE_INITING; - ASSERT(m->info); - // printf("Initing module %s... ", m->name); - status = m->info->std_ops(B_MODULE_INIT); - // printf("done (%s).\n", strerror(status)); - m->state = (status == B_OK) ? MODULE_READY : MODULE_LOADED; - - if (m->state == MODULE_READY && m->keep_loaded && m->addon) { - // one module (at least) was inited and request to never being - // unload from memory, so keep the corresponding addon loaded - // printf("module %s set B_KEEP_LOADED flag:\nmodule addon %s will never be unloaded!\n", - // m->name, m->addon->path); - m->addon->keep_loaded = true; - }; - break; - - case MODULE_READY: - status = B_OK; - break; - - case MODULE_INITING: // circular reference!!! - case MODULE_UNINITING: // initing a module currently unloading... - case MODULE_ERROR: // module failed to unload previously... - default: // Unknown module state!!! - status = B_ERROR; - break; - }; - - return status; -} - - -static status_t uninit_module(module * m) -{ - status_t status; - - ASSERT(m); - - switch (m->state) { - case MODULE_READY: - m->state = MODULE_UNINITING; - ASSERT(m->info); - // printf("Uniniting module %s... ", m->name); - status = m->info->std_ops(B_MODULE_UNINIT); - // printf("done (%s).\n", strerror(status)); - m->state = (status == B_OK) ? MODULE_LOADED : MODULE_ERROR; - break; - - case MODULE_LOADED: - // No need to uninit it, all is fine so. - status = B_OK; - break; - - case MODULE_INITING: // uniniting while initializing - case MODULE_UNINITING: // uniniting already pending - case MODULE_ERROR: // module failed previously... - default: // Unknown module state!!! - status = B_ERROR; - break; - }; - - return status; -} - - -static module * find_loaded_module_by_name(const char * name) -{ - module * m; - - LOCK_MODULES; - - m = g_modules; - while (m) { - if (strcmp(name, m->name) == 0) - break; - m = m->next; - }; - - UNLOCK_MODULES; - return m; -} - - -static module * find_loaded_module_by_id(uint32 id) -{ - module * m; - - LOCK_MODULES; - - m = g_modules; - while (m) { - if (m->id == id) - break; - m = m->next; - }; - - UNLOCK_MODULES; - return m; -} - -#if 0 -// #pragma mark - - -#define NET_CORE_MODULE_NAME "network/core/v1" -#define NET_ETHERNET_MODULE_NAME "network/interfaces/ethernet" -#define NET_IPV4_MODULE_NAME "network/protocols/ipv4/v1" - -#define MODULE_LIST_PREFIX "network" - -int main(int argc, char **argv) -{ - module_info * core; - module_info * ethernet; - module_info * ipv4; - char module_name[256]; - uint32 cookie; - size_t sz; - void * ml_cookie; - - new BApplication("application/x-vnd-OBOS-net_server"); - - printf("open_module_list(%s):\n", MODULE_LIST_PREFIX); - ml_cookie = open_module_list(MODULE_LIST_PREFIX); - sz = sizeof(module_name); - while(read_next_module_name(ml_cookie, module_name, &sz) == B_OK) { - if (strlen(module_name)) - printf(" %s\n", module_name); - sz = sizeof(module_name); - }; - close_module_list(ml_cookie); - printf("close_module_list()\n"); - // return 0; - - core = NULL; - get_module(NET_CORE_MODULE_NAME, (module_info **) &core); - - ethernet = NULL; - get_module(NET_ETHERNET_MODULE_NAME, (module_info **) ðernet); - - ipv4 = NULL; - get_module(NET_IPV4_MODULE_NAME, (module_info **) &ipv4); - - printf("get_next_loaded_module_name() test:\n"); - cookie = 0; - sz = sizeof(module_name); - while (get_next_loaded_module_name(&cookie, module_name, &sz) == B_OK) - printf("%ld: %s\n", cookie, module_name); - - if (ipv4) - put_module(NET_IPV4_MODULE_NAME); - - if (ethernet) - put_module(NET_ETHERNET_MODULE_NAME); - - if (core) - put_module(NET_CORE_MODULE_NAME); - - printf("get_next_loaded_module_name() test:\n"); - cookie = 0; - sz = sizeof(module_name); - while (get_next_loaded_module_name(&cookie, module_name, &sz) == B_OK) - printf("%ld: %s\n", cookie, module_name); - - delete be_app; - return 0; -} -#endif - - diff --git a/src/tests/kits/net/tcp_shell/Jamfile b/src/tests/kits/net/tcp_shell/Jamfile new file mode 100644 index 0000000000..697bb66edc --- /dev/null +++ b/src/tests/kits/net/tcp_shell/Jamfile @@ -0,0 +1,45 @@ +SubDir HAIKU_TOP src tests kits net tcp_shell ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +SubDirHdrs [ FDirName $(HAIKU_TOP) src tests add-ons kernel file_systems fs_shell ] ; +SubDirHdrs [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols tcp ] ; +SubDirHdrs [ FDirName $(HAIKU_TOP) src add-ons kernel network stack ] ; +UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; +UsePrivateHeaders kernel net shared ; + +SimpleTest tcp_shell : + tcp_tester.cpp + + # stack + net_buffer.cpp + utility.cpp + + # tcp + tcp.cpp + TCPEndpoint.cpp + BufferQueue.cpp + EndpointManager.cpp + + # misc + argv.c + ipv4_address.cpp + + : be libkernelland_emu.so +; + +SEARCH on [ FGristFiles + tcp.cpp TCPEndpoint.cpp BufferQueue.cpp EndpointManager.cpp + ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols tcp ] ; + +SEARCH on [ FGristFiles + ipv4_address.cpp + ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network protocols ipv4 ] ; + +SEARCH on [ FGristFiles + net_buffer.cpp utility.cpp + ] = [ FDirName $(HAIKU_TOP) src add-ons kernel network stack ] ; + +SEARCH on [ FGristFiles + argv.c + ] = [ FDirName $(HAIKU_TOP) src tests add-ons kernel file_systems fs_shell ] ; diff --git a/src/tests/kits/net/tcp_tester.cpp b/src/tests/kits/net/tcp_shell/tcp_tester.cpp similarity index 100% rename from src/tests/kits/net/tcp_tester.cpp rename to src/tests/kits/net/tcp_shell/tcp_tester.cpp