Add new code reorg files.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6341 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin 2004-01-27 08:05:13 +00:00
parent a98a451545
commit 58cdaa07fb
13 changed files with 1022 additions and 0 deletions

View File

@ -0,0 +1,3 @@
SubDir OBOS_TOP src tests kits net new_stack framings ;
SubInclude OBOS_TOP src tests kits net new_stack framings ethernet ;

View File

@ -0,0 +1,9 @@
SubDir OBOS_TOP src tests kits net new_stack framings ethernet ;
UseHeaders [ FDirName $(OBOS_TOP) src tests kits net new_stack headers ] ;
Addon <v2>ethernet_frame : userland network_v2 framings :
ethernet_frame.c
;
LinkSharedOSLibs <v2>ethernet_frame : <installed>new_stack_tester be ;

View File

@ -0,0 +1,175 @@
/* ethernet_framer.c - ethernet framing layer module
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <KernelExport.h>
#include <ByteOrder.h>
#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;
net_attribute_id ethernet_header_attr;
net_attribute_id ethernet_from_attr;
net_attribute_id ethernet_to_attr;
net_attribute_id 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_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
};

View File

@ -0,0 +1,5 @@
SubDir OBOS_TOP src tests kits net new_stack interfaces ;
SubInclude OBOS_TOP src tests kits net new_stack interfaces ether_drivers ;
SubInclude OBOS_TOP src tests kits net new_stack interfaces loopback ;
# SubInclude OBOS_TOP src tests kits net new_stack interfaces dialup ;

View File

@ -0,0 +1,9 @@
SubDir OBOS_TOP src tests kits net new_stack interfaces ether_drivers ;
UseHeaders [ FDirName $(OBOS_TOP) src tests kits net new_stack headers ] ;
Addon <v2>ether_drivers : userland network_v2 interfaces :
ether_drivers.c
;
LinkSharedOSLibs <v2>ether_drivers : <installed>new_stack_tester be ;

View File

@ -0,0 +1,339 @@
/* legacy_devices.c - generic ethernet legacy devices layer module
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/dirent.h>
#include <sys/stat.h>
#include <KernelExport.h>
#include <Drivers.h>
#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)
{
if (!buffer)
return B_ERROR;
// TODO!
dprintf("%s: process_output:\n", me->name);
g_stack->dump_buffer(buffer);
g_stack->delete_buffer(buffer, false);
return B_OK;
}
// #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;
return g_stack->register_layer(path, "ethernet/frame", 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_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
};

View File

@ -0,0 +1,9 @@
SubDir OBOS_TOP src tests kits net new_stack interfaces loopback ;
UseHeaders [ FDirName $(OBOS_TOP) src tests kits net new_stack headers ] ;
Addon <v2>loopback : userland network_v2 interfaces :
loopback.c
;
LinkSharedOSLibs <v2>loopback : <installed>new_stack_tester be ;

View File

@ -0,0 +1,96 @@
/* loopback.c - loopback interface module
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <KernelExport.h>
#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;
// -------------------
status_t init(net_layer *me)
{
dprintf("%s: initing layer\n", me->name);
return B_OK;
}
status_t uninit(net_layer *me)
{
dprintf("loopback: uniniting layer\n");
return B_OK;
}
status_t enable(net_layer *me, bool enable)
{
return B_OK;
}
status_t process_output(net_layer *me, net_buffer *buffer)
{
if (!buffer)
return B_ERROR;
// Here the magical loopback effect ;-)
return g_stack->send_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", "loopback/frame", 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
};

View File

@ -0,0 +1,5 @@
SubDir OBOS_TOP src tests kits net new_stack protocols ;
SubInclude OBOS_TOP src tests kits net new_stack protocols arp ;
SubInclude OBOS_TOP src tests kits net new_stack protocols ipv4 ;

View File

@ -0,0 +1,9 @@
SubDir OBOS_TOP src tests kits net new_stack protocols arp ;
UseHeaders [ FDirName $(OBOS_TOP) src tests kits net new_stack headers ] ;
Addon <v2>arp : userland network_v2 protocols :
arp.c
;
LinkSharedOSLibs <v2>arp : <installed>new_stack_tester be ;

View File

@ -0,0 +1,220 @@
/* ethernet.c - ethernet devices interface module
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <KernelExport.h>
#include <ByteOrder.h>
#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;
net_attribute_id 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_FRAMEREALY = 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 ==========\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, 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!
// dprintf("%s: packet %p is an ARP packet!\n", me->name, buffer);
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
};

View File

@ -0,0 +1,9 @@
SubDir OBOS_TOP src tests kits net new_stack protocols ipv4 ;
UseHeaders [ FDirName $(OBOS_TOP) src tests kits net new_stack headers ] ;
Addon <v2>ipv4 : userland network_v2 protocols :
ipv4.c
;
LinkSharedOSLibs <v2>ipv4 : <installed>new_stack_tester be ;

View File

@ -0,0 +1,134 @@
/* ipv4.c - ipv4 protocol module
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/dirent.h>
#include <sys/stat.h>
#include <KernelExport.h>
#include <ByteOrder.h>
#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;
net_attribute_id ethernet_protocol_attr;
// -------------------
static status_t init(net_layer *me)
{
printf("%s: initing layer\n", me->name);
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, NULL, (void **) &protocol, NULL) != B_OK)
return B_ERROR;
if (*protocol != htons(0x0800)) // IPv4 on Ethernet protocol value
return B_ERROR;
// TODO!
dprintf("%s: packet %p is an IPv4 packet!\n", me->name, 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
};