From 7f03fe56da18c9b998071c8d4a904aa558d97694 Mon Sep 17 00:00:00 2001 From: Philippe Houdoin Date: Sat, 3 Jan 2004 18:41:37 +0000 Subject: [PATCH] Net buffers attributes in usage... git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5890 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/net/new_stack/arp/arp.c | 147 ++++++++++++++++++----- src/tests/kits/net/new_stack/ipv4/ipv4.c | 132 ++++++++++++++++++++ 2 files changed, 249 insertions(+), 30 deletions(-) create mode 100644 src/tests/kits/net/new_stack/ipv4/ipv4.c diff --git a/src/tests/kits/net/new_stack/arp/arp.c b/src/tests/kits/net/new_stack/arp/arp.c index 75c423f9fa..78f6943eff 100644 --- a/src/tests/kits/net/new_stack/arp/arp.c +++ b/src/tests/kits/net/new_stack/arp/arp.c @@ -4,12 +4,9 @@ #include #include #include -#include -#include -#include - -#include +#include +#include #include "net_stack.h" @@ -19,17 +16,107 @@ 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 - + + // ------------------- status_t init(net_layer *me) { - printf("%s: initing layer\n", me->name); + dprintf("%s: initing layer\n", me->name); return B_OK; } status_t uninit(net_layer *me) { - printf("%s: uniniting layer\n", me->name); + dprintf("%s: uniniting layer\n", me->name); return B_OK; } @@ -40,26 +127,29 @@ status_t enable(net_layer *me, bool enable) } -status_t input_buffer(net_layer *me, net_buffer *buffer) +status_t process_input(net_layer *me, net_buffer *buffer) { -// uint16 *protocol; + uint16 *protocol; if (!buffer) return B_ERROR; -/* - if (g_stack->find_buffer_attribut(buffer, "ethernet:protocol", &protocol) != B_OK) + + if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, NULL, (void **) &protocol, NULL) != B_OK) return B_ERROR; - if (protocol != 0x0806) + 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; } -status_t output_buffer(net_layer *me, net_buffer *buffer) +status_t process_output(net_layer *me, net_buffer *buffer) { if (!buffer) return B_ERROR; @@ -70,38 +160,34 @@ status_t output_buffer(net_layer *me, net_buffer *buffer) // #pragma mark - -// #pragma mark - - status_t std_ops(int32 op, ...) { switch(op) { case B_MODULE_INIT: { status_t status; - net_layer *layer1, *layer2; + net_layer *layer; - printf("arp: B_MODULE_INIT\n"); + dprintf("arp: B_MODULE_INIT\n"); status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); if (status != B_OK) return status; - status = g_stack->register_layer("ethernet/arp", &nlmi, NULL, &layer1); - if (status != B_OK) - goto error1; + ethernet_protocol_attr = g_stack->register_attribute_id("ethernet:protocol"); - status = g_stack->register_layer("arp/ethernet", &nlmi, NULL, &layer2); + status = g_stack->register_layer("ARP", "ethernet/arp", 30, &nlmi, NULL, &layer); if (status != B_OK) - goto error2; - + goto error; + return B_OK; -error2: - g_stack->unregister_layer(layer1); -error1: + +error: + g_stack->unregister_layer(layer); put_module(NET_STACK_MODULE_NAME); return status; } case B_MODULE_UNINIT: - printf("arp: B_MODULE_UNINIT\n"); + dprintf("arp: B_MODULE_UNINIT\n"); put_module(NET_STACK_MODULE_NAME); break; @@ -121,8 +207,9 @@ struct net_layer_module_info nlmi = { init, uninit, enable, - output_buffer, - input_buffer + NULL, + process_input, + process_output }; _EXPORT module_info *modules[] = { diff --git a/src/tests/kits/net/new_stack/ipv4/ipv4.c b/src/tests/kits/net/new_stack/ipv4/ipv4.c new file mode 100644 index 0000000000..0581169b56 --- /dev/null +++ b/src/tests/kits/net/new_stack/ipv4/ipv4.c @@ -0,0 +1,132 @@ +/* ipv4.c - ipv4 protocol module + */ + +#include +#include +#include +#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; + +net_attribute_id ethernet_protocol_attr; + +// ------------------- +status_t init(net_layer *me) +{ + printf("%s: initing layer\n", me->name); + return B_OK; + +} + +status_t uninit(net_layer *me) +{ + printf("%s: uniniting layer\n", me->name); + return B_OK; +} + + +status_t enable(net_layer *me, bool enable) +{ + return B_OK; +} + + +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; +} + +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->register_attribute_id("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_LAYER_MODULES_ROOT "protocols/ipv4/v0", + 0, + std_ops + }, + + init, + uninit, + enable, + NULL, + process_input, + process_output +}; + +_EXPORT module_info *modules[] = { + (module_info*) &nlmi, // net_layer_module_info + NULL +};