Changes in / [5ccb15c:60b2b69] in mainline


Ignore:
Files:
14 added
27 deleted
52 edited

Legend:

Unmodified
Added
Removed
  • boot/Makefile.common

    r5ccb15c r60b2b69  
    9898        $(USPACE_PATH)/srv/fs/fat/fat \
    9999        $(USPACE_PATH)/srv/taskmon/taskmon \
    100         $(USPACE_PATH)/srv/hw/netif/dp8390/dp8390 \
    101         $(USPACE_PATH)/srv/hw/bus/usb/hcd/virtual/vhcd \
     100        $(USPACE_PATH)/srv/hw/netif/ne2000/ne2000 \
    102101        $(USPACE_PATH)/srv/net/netif/lo/lo \
    103102        $(USPACE_PATH)/srv/net/nil/eth/eth \
     
    133132        $(USPACE_PATH)/app/taskdump/taskdump \
    134133        $(USPACE_PATH)/app/tester/tester \
    135         $(USPACE_PATH)/app/test_serial/test_serial \
    136134        $(USPACE_PATH)/app/tetris/tetris \
    137135        $(USPACE_PATH)/app/trace/trace \
    138         $(USPACE_PATH)/app/netstart/netstart \
    139136        $(USPACE_PATH)/app/nettest1/nettest1 \
    140137        $(USPACE_PATH)/app/nettest2/nettest2 \
  • kernel/arch/amd64/include/interrupt.h

    r5ccb15c r60b2b69  
    5555#define IRQ_PIC_SPUR  7
    5656#define IRQ_MOUSE     12
    57 #define IRQ_DP8390    9
     57#define IRQ_NE2000    9
    5858
    5959/* This one must have four least significant bits set to ones */
  • kernel/arch/amd64/src/amd64.c

    r5ccb15c r60b2b69  
    238238                sysinfo_set_item_val(irqs_info, NULL, true);
    239239       
    240         sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390);
     240        sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000);
    241241}
    242242
  • kernel/arch/ia32/include/interrupt.h

    r5ccb15c r60b2b69  
    5555#define IRQ_PIC_SPUR  7
    5656#define IRQ_MOUSE     12
    57 #define IRQ_DP8390    5
     57#define IRQ_NE2000    5
    5858
    5959/* This one must have four least significant bits set to ones */
  • kernel/arch/ia32/src/ia32.c

    r5ccb15c r60b2b69  
    196196                sysinfo_set_item_val(irqs_info, NULL, true);
    197197       
    198         sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390);
     198        sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000);
    199199}
    200200
  • kernel/arch/ia64/include/interrupt.h

    r5ccb15c r60b2b69  
    6161#define IRQ_KBD    (0x01 + LEGACY_INTERRUPT_BASE)
    6262#define IRQ_MOUSE  (0x0c + LEGACY_INTERRUPT_BASE)
    63 #define IRQ_DP8390 (0x09 + LEGACY_INTERRUPT_BASE)
     63#define IRQ_NE2000 (0x09 + LEGACY_INTERRUPT_BASE)
    6464
    6565/** General Exception codes. */
  • kernel/arch/ia64/src/ia64.c

    r5ccb15c r60b2b69  
    222222#endif
    223223
    224         sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390);
     224        sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000);
    225225
    226226        sysinfo_set_item_val("ia64_iospace", NULL, true);
  • kernel/generic/include/ddi/ddi.h

    r5ccb15c r60b2b69  
    5454extern sysarg_t sys_physmem_map(sysarg_t, sysarg_t, sysarg_t, sysarg_t);
    5555extern sysarg_t sys_iospace_enable(ddi_ioarg_t *);
    56 extern sysarg_t sys_interrupt_enable(int irq, int enable);
    5756
    5857/*
  • kernel/generic/include/syscall/syscall.h

    r5ccb15c r60b2b69  
    8282        SYS_PHYSMEM_MAP,
    8383        SYS_IOSPACE_ENABLE,
    84         SYS_INTERRUPT_ENABLE,
    8584       
    8685        SYS_SYSINFO_GET_TAG,
  • kernel/generic/src/ddi/ddi.c

    r5ccb15c r60b2b69  
    258258}
    259259
    260 /** Disable or enable specified interrupts.
    261  *
    262  * @param irq the interrupt to be enabled/disabled.
    263  * @param enable if true enable the interrupt, disable otherwise.
    264  *
    265  * @retutn Zero on success, error code otherwise.
    266  */
    267 sysarg_t sys_interrupt_enable(int irq, int enable)
    268 {
    269 /* FIXME: this needs to be generic code, or better not be in kernel at all. */
    270 #if 0
    271         cap_t task_cap = cap_get(TASK);
    272         if (!(task_cap & CAP_IRQ_REG))
    273                 return EPERM;
    274                
    275         if (irq < 0 || irq > 16) {
    276                 return EINVAL;
    277         }
    278        
    279         uint16_t irq_mask = (uint16_t)(1 << irq);
    280         if (enable) {
    281                 trap_virtual_enable_irqs(irq_mask);
    282         } else {
    283                 trap_virtual_disable_irqs(irq_mask);
    284         }
    285        
    286 #endif
    287         return 0;
    288 }
    289 
    290260/** @}
    291261 */
  • kernel/generic/src/mm/slab.c

    r5ccb15c r60b2b69  
    806806}
    807807
    808 /** Go through all caches and reclaim what is possible
    809  *
    810  * Interrupts must be disabled before calling this function,
    811  * otherwise  memory allocation from interrupts can deadlock.
    812  *
    813  */
     808/** Go through all caches and reclaim what is possible */
    814809size_t slab_reclaim(unsigned int flags)
    815810{
    816         irq_spinlock_lock(&slab_cache_lock, false);
     811        irq_spinlock_lock(&slab_cache_lock, true);
    817812       
    818813        size_t frames = 0;
     
    824819        }
    825820       
    826         irq_spinlock_unlock(&slab_cache_lock, false);
     821        irq_spinlock_unlock(&slab_cache_lock, true);
    827822       
    828823        return frames;
  • kernel/generic/src/syscall/syscall.c

    r5ccb15c r60b2b69  
    171171        (syshandler_t) sys_physmem_map,
    172172        (syshandler_t) sys_iospace_enable,
    173         (syshandler_t) sys_interrupt_enable,
    174173       
    175174        /* Sysinfo syscalls */
  • uspace/Makefile

    r5ccb15c r60b2b69  
    8282        srv/hw/char/i8042 \
    8383        srv/hw/char/s3c24xx_uart \
    84         srv/hw/netif/dp8390 \
     84        srv/hw/netif/ne2000 \
    8585        srv/net/netif/lo \
    8686        srv/net/il/arp \
  • uspace/app/trace/syscalls.c

    r5ccb15c r60b2b69  
    7373    [SYS_PHYSMEM_MAP] = { "physmem_map",                4,      V_ERRNO },
    7474    [SYS_IOSPACE_ENABLE] = { "iospace_enable",          1,      V_ERRNO },
    75     [SYS_INTERRUPT_ENABLE] = { "interrupt_enable",      2,      V_ERRNO },
    7675
    7776    [SYS_SYSINFO_GET_TAG] = { "sysinfo_get_tag",                2,      V_INTEGER },
  • uspace/doc/doxygroups.h

    r5ccb15c r60b2b69  
    4343
    4444                        /**
    45                          * @defgroup dp8390 Generic DP8390 network interface family service
     45                         * @defgroup ne2000 NE2000 network interface service
    4646                         * @ingroup netif
    4747                         */
    48 
    49                                 /**
    50                                  * @defgroup ne2k NE2000 network interface family
    51                                  * @ingroup dp8390
    52                                  */
    5348
    5449                /**
  • uspace/drv/ns8250/ns8250.c

    r5ccb15c r60b2b69  
    431431{
    432432        ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data;
    433         int res;
    434        
    435         /* Enable interrupt globally. */
    436         res = interrupt_enable(data->irq);
    437         if (res != EOK)
    438                 return res;
    439433       
    440434        /* Enable interrupt on the serial port. */
  • uspace/lib/c/generic/ddi.c

    r5ccb15c r60b2b69  
    9696}
    9797
    98 /** Enable an interrupt.
    99  *
    100  * @param irq the interrupt.
    101  *
    102  * @return Zero on success, negative error code otherwise.
    103  */
    104 int interrupt_enable(int irq)
    105 {
    106         return __SYSCALL2(SYS_INTERRUPT_ENABLE, (sysarg_t) irq, 1);
    107 }
    108 
    109 /** Disable an interrupt.
    110  *
    111  * @param irq the interrupt.
    112  *
    113  * @return Zero on success, negative error code otherwise.
    114  */
    115 int interrupt_disable(int irq)
    116 {
    117         return __SYSCALL2(SYS_INTERRUPT_ENABLE, (sysarg_t) irq, 0);
    118 }
    119 
    12098/** Enable PIO for specified I/O range.
    12199 *
  • uspace/lib/c/generic/devman.c

    r5ccb15c r60b2b69  
    7979                }
    8080               
    81                 if (flags & IPC_FLAG_BLOCKING)
     81                if (flags & IPC_FLAG_BLOCKING) {
    8282                        devman_phone_client = async_connect_me_to_blocking(
    8383                            PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    84                 else
     84                } else {
    8585                        devman_phone_client = async_connect_me_to(PHONE_NS,
    8686                            SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
     87                }
    8788               
    8889                fibril_mutex_unlock(&devman_phone_mutex);
  • uspace/lib/c/include/ddi.h

    r5ccb15c r60b2b69  
    4242extern int iospace_enable(task_id_t, void *, unsigned long);
    4343extern int pio_enable(void *, size_t, void **);
    44 extern int interrupt_enable(int);
    45 extern int interrupt_disable(int);
    4644
    4745#endif
  • uspace/lib/c/include/ipc/il.h

    r5ccb15c r60b2b69  
    3333/** @file
    3434 * Internetwork layer modules messages.
    35  * @see il_interface.h
     35 * @see il_remote.h
    3636 * @see ip_interface.h
    3737 */
     
    4545/** Internet layer modules messages. */
    4646typedef enum {
    47         /** New device message.
    48          * @see ip_device_req()
    49          */
    50         NET_IL_DEVICE = NET_IL_FIRST,
    5147        /** Device state changed message.
    5248         * @see il_device_state_msg()
    5349         */
    54         NET_IL_DEVICE_STATE,
     50        NET_IL_DEVICE_STATE = NET_IL_FIRST,
     51       
    5552        /** Device MTU changed message.
    5653         * @see il_mtu_changed_msg()
    5754         */
    5855        NET_IL_MTU_CHANGED,
    59         /** Packet size message.
    60          * @see il_packet_size_req()
    61          */
    62         NET_IL_PACKET_SPACE,
     56       
    6357        /** Packet received message.
    6458         * @see il_received_msg()
    6559         */
    66         NET_IL_RECEIVED,
    67         /** Packet send message.
    68          * @see il_send_msg()
    69          */
    70         NET_IL_SEND
     60        NET_IL_RECEIVED
    7161} il_messages;
    7262
  • uspace/lib/c/include/ipc/ip.h

    r5ccb15c r60b2b69  
    4747/** IP module messages. */
    4848typedef enum {
     49        /** New device message.
     50         * @see ip_device_req()
     51         */
     52        NET_IP_DEVICE = NET_IP_FIRST,
     53       
    4954        /** Adds the routing entry.
    5055         * @see ip_add_route()
    5156         */
    52         NET_IP_ADD_ROUTE = NET_IP_FIRST,
     57        NET_IP_ADD_ROUTE,
    5358       
    5459        /** Gets the actual route information.
     
    6570         * @see ip_set_default_gateway()
    6671         */
    67         NET_IP_SET_GATEWAY
     72        NET_IP_SET_GATEWAY,
     73       
     74        /** Packet size message.
     75         * @see ip_packet_size_req()
     76         */
     77        NET_IP_PACKET_SPACE,
     78       
     79        /** Packet send message.
     80         * @see ip_send_msg()
     81         */
     82        NET_IP_SEND
    6883} ip_messages;
    6984
  • uspace/lib/c/include/ipc/services.h

    r5ccb15c r60b2b69  
    5454        SERVICE_NETWORKING,
    5555        SERVICE_LO,
    56         SERVICE_DP8390,
     56        SERVICE_NE2000,
    5757        SERVICE_ETHERNET,
    5858        SERVICE_NILDUMMY,
  • uspace/lib/net/Makefile

    r5ccb15c r60b2b69  
    4343        netif/netif_skel.c \
    4444        nil/nil_remote.c \
    45         il/il_interface.c \
     45        nil/nil_skel.c \
     46        il/il_remote.c \
     47        il/il_skel.c \
    4648        il/ip_remote.c \
    4749        il/ip_client.c \
     
    5052        tl/icmp_client.c \
    5153        tl/socket_core.c \
    52         tl/tl_interface.c \
    53         tl/tl_common.c
     54        tl/tl_common.c \
     55        tl/tl_remote.c \
     56        tl/tl_skel.c
    5457
    5558include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/net/generic/protocol_map.c

    r5ccb15c r60b2b69  
    5050        switch (nil) {
    5151        case SERVICE_ETHERNET:
    52         case SERVICE_DP8390:
     52        case SERVICE_NE2000:
    5353                switch (il) {
    5454                case SERVICE_IP:
     
    7676        switch (nil) {
    7777        case SERVICE_ETHERNET:
    78         case SERVICE_DP8390:
     78        case SERVICE_NE2000:
    7979                switch (protocol) {
    8080                case ETH_P_IP:
     
    139139        switch (nil) {
    140140        case SERVICE_ETHERNET:
    141         case SERVICE_DP8390:
     141        case SERVICE_NE2000:
    142142                return HW_ETHER;
    143143        default:
  • uspace/lib/net/il/ip_remote.c

    r5ccb15c r60b2b69  
    3636 *
    3737 * @see ip_interface.h
    38  * @see il_interface.h
     38 * @see il_remote.h
    3939 *
    4040 */
     
    121121    services_t service)
    122122{
    123         return generic_device_req_remote(ip_phone, NET_IL_DEVICE, device_id, 0,
     123        return generic_device_req_remote(ip_phone, NET_IP_DEVICE, device_id, 0,
    124124            service);
    125125}
     
    188188    packet_dimension_t *packet_dimension)
    189189{
    190         return generic_packet_size_req_remote(ip_phone, NET_IL_PACKET_SPACE,
     190        return generic_packet_size_req_remote(ip_phone, NET_IP_PACKET_SPACE,
    191191            device_id, packet_dimension);
    192192}
     
    228228    services_t sender, services_t error)
    229229{
    230         return generic_send_msg_remote(ip_phone, NET_IL_SEND, device_id,
     230        return generic_send_msg_remote(ip_phone, NET_IP_SEND, device_id,
    231231            packet_get_id(packet), sender, error);
    232232}
  • uspace/lib/net/include/nil_remote.h

    r5ccb15c r60b2b69  
    3737#include <net/device.h>
    3838#include <net/packet.h>
     39#include <generic.h>
    3940
    40 extern int nil_device_state_msg_remote(int, device_id_t, int);
    41 extern int nil_received_msg_remote(int, device_id_t, packet_t *, services_t);
     41#define nil_bind_service(service, device_id, me, receiver) \
     42        bind_service(service, device_id, me, 0, receiver)
     43
     44#define nil_packet_size_req(nil_phone, device_id, packet_dimension) \
     45        generic_packet_size_req_remote(nil_phone, NET_NIL_PACKET_SPACE, \
     46            device_id, packet_dimension)
     47
     48#define nil_get_addr_req(nil_phone, device_id, address, data) \
     49        generic_get_addr_req(nil_phone, NET_NIL_ADDR, device_id, address, data)
     50
     51#define nil_get_broadcast_addr_req(nil_phone, device_id, address, data) \
     52        generic_get_addr_req(nil_phone, NET_NIL_BROADCAST_ADDR, device_id, \
     53            address, data)
     54
     55#define nil_send_msg(nil_phone, device_id, packet, sender) \
     56        generic_send_msg_remote(nil_phone, NET_NIL_SEND, device_id, \
     57            packet_get_id(packet), sender, 0)
     58
     59#define nil_device_req(nil_phone, device_id, mtu, netif_service) \
     60        generic_device_req_remote(nil_phone, NET_NIL_DEVICE, device_id, mtu, \
     61            netif_service)
     62
     63extern int nil_device_state_msg(int, device_id_t, int);
     64extern int nil_received_msg(int, device_id_t, packet_t *, services_t);
    4265
    4366#endif
  • uspace/lib/net/netif/netif_skel.c

    r5ccb15c r60b2b69  
    3333/** @file
    3434 * Network interface module skeleton implementation.
    35  * @see netif.h
     35 * @see netif_skel.h
    3636 */
    3737
     
    5252#include <adt/measured_strings.h>
    5353#include <net/device.h>
    54 #include <nil_interface.h>
    5554#include <netif_skel.h>
     55#include <nil_remote.h>
    5656
    5757DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t);
     
    130130        if (result > NETIF_NULL) {
    131131                int phone = device->nil_phone;
     132                nil_device_state_msg(phone, device_id, result);
    132133                fibril_rwlock_write_unlock(&netif_globals.lock);
    133                 nil_device_state_msg(phone, device_id, result);
    134134                return EOK;
    135135        }
     
    166166        if (result > NETIF_NULL) {
    167167                int phone = device->nil_phone;
     168                nil_device_state_msg(phone, device_id, result);
    168169                fibril_rwlock_write_unlock(&netif_globals.lock);
    169                 nil_device_state_msg(phone, device_id, result);
    170170                return EOK;
    171171        }
  • uspace/lib/net/nil/nil_remote.c

    r5ccb15c r60b2b69  
    3333/** @file
    3434 * Network interface layer interface implementation for remote modules.
    35  * @see nil_interface.h
     35 * @see nil_remote.h
    3636 */
    3737
    3838#include <nil_remote.h>
    39 #include <nil_interface.h>
    4039#include <generic.h>
    4140#include <net/device.h>
    4241#include <net/packet.h>
    4342#include <packet_client.h>
    44 
    4543#include <ipc/nil.h>
    4644
    4745/** Notify the network interface layer about the device state change.
    4846 *
    49  * @param[in] nil_phone The network interface layer phone.
    50  * @param[in] device_id The device identifier.
    51  * @param[in] state     The new device state.
    52  * @return              EOK on success.
    53  * @return              Other error codes as defined for each specific module
    54  *                      device state function.
     47 * @param[in] nil_phone Network interface layer phone.
     48 * @param[in] device_id Device identifier.
     49 * @param[in] state     New device state.
     50 *
     51 * @return EOK on success.
     52 * @return Other error codes as defined for each specific module
     53 *         device state function.
     54 *
    5555 */
    56 int nil_device_state_msg_remote(int nil_phone, device_id_t device_id, int state)
     56int nil_device_state_msg(int nil_phone, device_id_t device_id, int state)
    5757{
    5858        return generic_device_state_msg_remote(nil_phone, NET_NIL_DEVICE_STATE,
     
    6565 * upper layers.
    6666 *
    67  * @param[in] nil_phone The network interface layer phone.
    68  * @param[in] device_id The source device identifier.
    69  * @param[in] packet    The received packet or the received packet queue.
    70  * @param target        The target service. Ignored parameter.
    71  * @return              EOK on success.
    72  * @return              Other error codes as defined for each specific module
    73  *                      received function.
     67 * @param[in] nil_phone Network interface layer phone.
     68 * @param[in] device_id Source device identifier.
     69 * @param[in] packet    Received packet or the received packet queue.
     70 * @param[in] target    Target service. Ignored parameter.
     71 *
     72 * @return EOK on success.
     73 * @return Other error codes as defined for each specific module
     74 *         received function.
     75 *
    7476 */
    75 int nil_received_msg_remote(int nil_phone, device_id_t device_id,
     77int nil_received_msg(int nil_phone, device_id_t device_id,
    7678    packet_t *packet, services_t target)
    7779{
  • uspace/lib/net/tl/tl_common.c

    r5ccb15c r60b2b69  
    4242#include <ip_remote.h>
    4343#include <ip_interface.h>
    44 #include <tl_interface.h>
     44#include <tl_remote.h>
    4545
    4646#include <net/socket_codes.h>
  • uspace/lib/usb/src/usbdrvreq.c

    r5ccb15c r60b2b69  
    6060#define PREPARE_SETUP_PACKET(name, p_direction, p_type, p_recipient, \
    6161    p_request, p_value, p_index, p_length) \
    62         usb_device_request_setup_packet_t setup_packet = { \
     62        usb_device_request_setup_packet_t name = { \
    6363                .request_type = \
    6464                        ((p_direction) == USB_DIRECTION_IN ? 128 : 0) \
  • uspace/srv/net/cfg/ne2k

    r5ccb15c r60b2b69  
    33NAME=ne2k
    44
    5 NETIF=dp8390
     5NETIF=ne2000
    66NIL=eth
    77IL=ip
     
    1717IP_ADDR=10.0.2.15
    1818IP_ROUTING=yes
    19 IP_NETMASK=255.255.255.240
     19IP_NETMASK=255.255.255.0
    2020IP_BROADCAST=10.0.2.255
    2121IP_GATEWAY=10.0.2.2
  • uspace/srv/net/il/arp/Makefile

    r5ccb15c r60b2b69  
    3434
    3535SOURCES = \
    36         arp.c \
    37         arp_module.c
     36        arp.c
    3837
    3938include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/il/arp/arp.c

    r5ccb15c r60b2b69  
    3636 */
    3737
    38 #include "arp.h"
    39 #include "arp_header.h"
    40 #include "arp_oc.h"
    41 #include "arp_module.h"
    42 
    4338#include <async.h>
    4439#include <malloc.h>
    4540#include <mem.h>
    4641#include <fibril_synch.h>
     42#include <assert.h>
    4743#include <stdio.h>
    4844#include <str.h>
     
    5450#include <ipc/arp.h>
    5551#include <ipc/il.h>
     52#include <ipc/nil.h>
    5653#include <byteorder.h>
    5754#include <errno.h>
    58 
    5955#include <net/modules.h>
    6056#include <net/device.h>
    6157#include <net/packet.h>
    62 
    63 #include <nil_interface.h>
     58#include <nil_remote.h>
    6459#include <protocol_map.h>
    6560#include <packet_client.h>
    6661#include <packet_remote.h>
    67 #include <il_interface.h>
    68 #include <il_local.h>
    69 
     62#include <il_remote.h>
     63#include <il_skel.h>
     64#include "arp.h"
    7065
    7166/** ARP module name. */
     
    7368
    7469/** Number of microseconds to wait for an ARP reply. */
    75 #define ARP_TRANS_WAIT  1000000
     70#define ARP_TRANS_WAIT  1000000
     71
     72/** @name ARP operation codes definitions */
     73/*@{*/
     74
     75/** REQUEST operation code. */
     76#define ARPOP_REQUEST  1
     77
     78/** REPLY operation code. */
     79#define ARPOP_REPLY  2
     80
     81/*@}*/
     82
     83/** Type definition of an ARP protocol header.
     84 * @see arp_header
     85 */
     86typedef struct arp_header arp_header_t;
     87
     88/** ARP protocol header. */
     89struct arp_header {
     90        /**
     91         * Hardware type identifier.
     92         * @see hardware.h
     93         */
     94        uint16_t hardware;
     95       
     96        /** Protocol identifier. */
     97        uint16_t protocol;
     98        /** Hardware address length in bytes. */
     99        uint8_t hardware_length;
     100        /** Protocol address length in bytes. */
     101        uint8_t protocol_length;
     102       
     103        /**
     104         * ARP packet type.
     105         * @see arp_oc.h
     106         */
     107        uint16_t operation;
     108} __attribute__ ((packed));
    76109
    77110/** ARP global data. */
     
    88121                trans->hw_addr = NULL;
    89122        }
     123       
    90124        fibril_condvar_broadcast(&trans->cv);
    91125}
     
    94128{
    95129        int count;
    96         arp_trans_t *trans;
    97 
     130       
    98131        for (count = arp_addr_count(addresses) - 1; count >= 0; count--) {
    99                 trans = arp_addr_items_get_index(&addresses->values, count);
     132                arp_trans_t *trans = arp_addr_items_get_index(&addresses->values,
     133                    count);
    100134                if (trans)
    101135                        arp_clear_trans(trans);
     
    103137}
    104138
    105 
    106 /** Clears the device specific data.
    107  *
    108  * @param[in] device    The device specific data.
     139/** Clear the device specific data.
     140 *
     141 * @param[in] device Device specific data.
    109142 */
    110143static void arp_clear_device(arp_device_t *device)
    111144{
    112145        int count;
    113         arp_proto_t *proto;
    114 
     146       
    115147        for (count = arp_protos_count(&device->protos) - 1; count >= 0;
    116148            count--) {
    117                 proto = arp_protos_get_index(&device->protos, count);
     149                arp_proto_t *proto = arp_protos_get_index(&device->protos,
     150                    count);
     151               
    118152                if (proto) {
    119153                        if (proto->addr)
    120154                                free(proto->addr);
     155                       
    121156                        if (proto->addr_data)
    122157                                free(proto->addr_data);
     158                       
    123159                        arp_clear_addr(&proto->addresses);
    124160                        arp_addr_destroy(&proto->addresses);
    125161                }
    126162        }
     163       
    127164        arp_protos_clear(&device->protos);
    128165}
     
    131168{
    132169        int count;
    133         arp_device_t *device;
    134 
     170       
    135171        fibril_mutex_lock(&arp_globals.lock);
    136172        for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0;
    137173            count--) {
    138                 device = arp_cache_get_index(&arp_globals.cache, count);
     174                arp_device_t *device = arp_cache_get_index(&arp_globals.cache,
     175                    count);
     176               
    139177                if (device) {
    140178                        arp_clear_device(device);
    141179                        if (device->addr_data)
    142180                                free(device->addr_data);
     181                       
    143182                        if (device->broadcast_data)
    144183                                free(device->broadcast_data);
    145184                }
    146185        }
     186       
    147187        arp_cache_clear(&arp_globals.cache);
    148188        fibril_mutex_unlock(&arp_globals.lock);
    149         printf("Cache cleaned\n");
     189       
    150190        return EOK;
    151191}
     
    154194    services_t protocol, measured_string_t *address)
    155195{
    156         arp_device_t *device;
    157         arp_proto_t *proto;
    158         arp_trans_t *trans;
    159 
    160196        fibril_mutex_lock(&arp_globals.lock);
    161         device = arp_cache_find(&arp_globals.cache, device_id);
     197       
     198        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    162199        if (!device) {
    163200                fibril_mutex_unlock(&arp_globals.lock);
    164201                return ENOENT;
    165202        }
    166         proto = arp_protos_find(&device->protos, protocol);
     203       
     204        arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
    167205        if (!proto) {
    168206                fibril_mutex_unlock(&arp_globals.lock);
    169207                return ENOENT;
    170208        }
    171         trans = arp_addr_find(&proto->addresses, address->value, address->length);
     209       
     210        arp_trans_t *trans = arp_addr_find(&proto->addresses, address->value,
     211            address->length);
    172212        if (trans)
    173213                arp_clear_trans(trans);
     214       
    174215        arp_addr_exclude(&proto->addresses, address->value, address->length);
     216       
    175217        fibril_mutex_unlock(&arp_globals.lock);
    176218        return EOK;
    177219}
    178220
    179 
    180221static int arp_clear_device_req(int arp_phone, device_id_t device_id)
    181222{
    182         arp_device_t *device;
    183 
    184223        fibril_mutex_lock(&arp_globals.lock);
    185         device = arp_cache_find(&arp_globals.cache, device_id);
     224       
     225        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    186226        if (!device) {
    187227                fibril_mutex_unlock(&arp_globals.lock);
    188228                return ENOENT;
    189229        }
     230       
    190231        arp_clear_device(device);
    191         printf("Device %d cleared\n", device_id);
     232       
    192233        fibril_mutex_unlock(&arp_globals.lock);
    193234        return EOK;
    194235}
    195236
    196 /** Creates new protocol specific data.
    197  *
    198  * Allocates and returns the needed memory block as the proto parameter.
    199  *
    200  * @param[out] proto    The allocated protocol specific data.
    201  * @param[in] service   The protocol module service.
    202  * @param[in] address   The actual protocol device address.
    203  * @return              EOK on success.
    204  * @return              ENOMEM if there is not enough memory left.
     237/** Create new protocol specific data.
     238 *
     239 * Allocate and return the needed memory block as the proto parameter.
     240 *
     241 * @param[out] proto   Allocated protocol specific data.
     242 * @param[in]  service Protocol module service.
     243 * @param[in]  address Actual protocol device address.
     244 *
     245 * @return EOK on success.
     246 * @return ENOMEM if there is not enough memory left.
     247 *
    205248 */
    206249static int arp_proto_create(arp_proto_t **proto, services_t service,
    207250    measured_string_t *address)
    208251{
    209         int rc;
    210 
    211252        *proto = (arp_proto_t *) malloc(sizeof(arp_proto_t));
    212253        if (!*proto)
     
    217258        (*proto)->addr_data = address->value;
    218259       
    219         rc = arp_addr_initialize(&(*proto)->addresses);
     260        int rc = arp_addr_initialize(&(*proto)->addresses);
    220261        if (rc != EOK) {
    221262                free(*proto);
     
    226267}
    227268
    228 /** Registers the device.
    229  *
    230  * Creates new device entry in the cache or updates the protocol address if the
    231  * device with the device identifier and the driver service exists.
    232  *
    233  * @param[in] device_id The device identifier.
    234  * @param[in] service   The device driver service.
    235  * @param[in] protocol  The protocol service.
    236  * @param[in] address   The actual device protocol address.
    237  * @return              EOK on success.
    238  * @return              EEXIST if another device with the same device identifier
    239  *                      and different driver service exists.
    240  * @return              ENOMEM if there is not enough memory left.
    241  * @return              Other error codes as defined for the
    242  *                      measured_strings_return() function.
    243  */
    244 static int arp_device_message(device_id_t device_id, services_t service,
    245     services_t protocol, measured_string_t *address)
    246 {
    247         arp_device_t *device;
    248         arp_proto_t *proto;
    249         hw_type_t hardware;
    250         int index;
     269/** Process the received ARP packet.
     270 *
     271 * Update the source hardware address if the source entry exists or the packet
     272 * is targeted to my protocol address.
     273 *
     274 * Respond to the ARP request if the packet is the ARP request and is
     275 * targeted to my address.
     276 *
     277 * @param[in]     device_id Source device identifier.
     278 * @param[in,out] packet    Received packet.
     279 *
     280 * @return EOK on success and the packet is no longer needed.
     281 * @return One on success and the packet has been reused.
     282 * @return EINVAL if the packet is too small to carry an ARP
     283 *         packet.
     284 * @return EINVAL if the received address lengths differs from
     285 *         the registered values.
     286 * @return ENOENT if the device is not found in the cache.
     287 * @return ENOENT if the protocol for the device is not found in
     288 *         the cache.
     289 * @return ENOMEM if there is not enough memory left.
     290 *
     291 */
     292static int arp_receive_message(device_id_t device_id, packet_t *packet)
     293{
    251294        int rc;
    252 
    253         fibril_mutex_lock(&arp_globals.lock);
    254 
    255         /* An existing device? */
    256         device = arp_cache_find(&arp_globals.cache, device_id);
    257 
    258         if (device) {
    259                 if (device->service != service) {
    260                         printf("Device %d already exists\n", device->device_id);
    261                         fibril_mutex_unlock(&arp_globals.lock);
    262                         return EEXIST;
    263                 }
    264                 proto = arp_protos_find(&device->protos, protocol);
    265                 if (proto) {
    266                         free(proto->addr);
    267                         free(proto->addr_data);
    268                         proto->addr = address;
    269                         proto->addr_data = address->value;
    270                 } else {
    271                         rc = arp_proto_create(&proto, protocol, address);
    272                         if (rc != EOK) {
    273                                 fibril_mutex_unlock(&arp_globals.lock);
    274                                 return rc;
    275                         }
    276                         index = arp_protos_add(&device->protos, proto->service,
    277                             proto);
    278                         if (index < 0) {
    279                                 fibril_mutex_unlock(&arp_globals.lock);
    280                                 free(proto);
    281                                 return index;
    282                         }
    283                         printf("New protocol added:\n\tdevice id\t= "
    284                             "%d\n\tproto\t= %d", device_id, protocol);
    285                 }
    286         } else {
    287                 hardware = hardware_map(service);
    288                 if (!hardware)
    289                         return ENOENT;
    290                
    291                 /* Create a new device */
    292                 device = (arp_device_t *) malloc(sizeof(arp_device_t));
    293                 if (!device) {
    294                         fibril_mutex_unlock(&arp_globals.lock);
    295                         return ENOMEM;
    296                 }
    297                 device->hardware = hardware;
    298                 device->device_id = device_id;
    299                 rc = arp_protos_initialize(&device->protos);
    300                 if (rc != EOK) {
    301                         fibril_mutex_unlock(&arp_globals.lock);
    302                         free(device);
    303                         return rc;
    304                 }
    305                 rc = arp_proto_create(&proto, protocol, address);
    306                 if (rc != EOK) {
    307                         fibril_mutex_unlock(&arp_globals.lock);
    308                         free(device);
    309                         return rc;
    310                 }
    311                 index = arp_protos_add(&device->protos, proto->service, proto);
    312                 if (index < 0) {
    313                         fibril_mutex_unlock(&arp_globals.lock);
    314                         arp_protos_destroy(&device->protos);
    315                         free(device);
    316                         return index;
    317                 }
    318                 device->service = service;
    319                
    320                 /* Bind the new one */
    321                 device->phone = nil_bind_service(device->service,
    322                     (sysarg_t) device->device_id, SERVICE_ARP,
    323                     arp_globals.client_connection);
    324                 if (device->phone < 0) {
    325                         fibril_mutex_unlock(&arp_globals.lock);
    326                         arp_protos_destroy(&device->protos);
    327                         free(device);
    328                         return EREFUSED;
    329                 }
    330                
    331                 /* Get packet dimensions */
    332                 rc = nil_packet_size_req(device->phone, device_id,
    333                     &device->packet_dimension);
    334                 if (rc != EOK) {
    335                         fibril_mutex_unlock(&arp_globals.lock);
    336                         arp_protos_destroy(&device->protos);
    337                         free(device);
    338                         return rc;
    339                 }
    340                
    341                 /* Get hardware address */
    342                 rc = nil_get_addr_req(device->phone, device_id, &device->addr,
    343                     &device->addr_data);
    344                 if (rc != EOK) {
    345                         fibril_mutex_unlock(&arp_globals.lock);
    346                         arp_protos_destroy(&device->protos);
    347                         free(device);
    348                         return rc;
    349                 }
    350                
    351                 /* Get broadcast address */
    352                 rc = nil_get_broadcast_addr_req(device->phone, device_id,
    353                     &device->broadcast_addr, &device->broadcast_data);
    354                 if (rc != EOK) {
    355                         fibril_mutex_unlock(&arp_globals.lock);
    356                         free(device->addr);
    357                         free(device->addr_data);
    358                         arp_protos_destroy(&device->protos);
    359                         free(device);
    360                         return rc;
    361                 }
    362                
    363                 rc = arp_cache_add(&arp_globals.cache, device->device_id,
    364                     device);
    365                 if (rc != EOK) {
    366                         fibril_mutex_unlock(&arp_globals.lock);
    367                         free(device->addr);
    368                         free(device->addr_data);
    369                         free(device->broadcast_addr);
    370                         free(device->broadcast_data);
    371                         arp_protos_destroy(&device->protos);
    372                         free(device);
    373                         return rc;
    374                 }
    375                 printf("%s: Device registered (id: %d, type: 0x%x, service: %d,"
    376                     " proto: %d)\n", NAME, device->device_id, device->hardware,
    377                     device->service, protocol);
    378         }
    379         fibril_mutex_unlock(&arp_globals.lock);
    380        
    381         return EOK;
    382 }
    383 
    384 /** Initializes the ARP module.
    385  *
    386  *  @param[in] client_connection The client connection processing function.
    387  *                      The module skeleton propagates its own one.
    388  *  @return             EOK on success.
    389  *  @return             ENOMEM if there is not enough memory left.
    390  */
    391 int arp_initialize(async_client_conn_t client_connection)
    392 {
    393         int rc;
    394 
    395         fibril_mutex_initialize(&arp_globals.lock);
    396         fibril_mutex_lock(&arp_globals.lock);
    397         arp_globals.client_connection = client_connection;
    398         rc = arp_cache_initialize(&arp_globals.cache);
    399         fibril_mutex_unlock(&arp_globals.lock);
    400        
    401         return rc;
    402 }
    403 
    404 /** Updates the device content length according to the new MTU value.
    405  *
    406  * @param[in] device_id The device identifier.
    407  * @param[in] mtu       The new mtu value.
    408  * @return              ENOENT if device is not found.
    409  * @return              EOK on success.
    410  */
    411 static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
    412 {
    413         arp_device_t *device;
    414 
    415         fibril_mutex_lock(&arp_globals.lock);
    416         device = arp_cache_find(&arp_globals.cache, device_id);
    417         if (!device) {
    418                 fibril_mutex_unlock(&arp_globals.lock);
    419                 return ENOENT;
    420         }
    421         device->packet_dimension.content = mtu;
    422         fibril_mutex_unlock(&arp_globals.lock);
    423         printf("arp - device %d changed mtu to %zu\n\n", device_id, mtu);
    424         return EOK;
    425 }
    426 
    427 /** Processes the received ARP packet.
    428  *
    429  * Updates the source hardware address if the source entry exists or the packet
    430  * is targeted to my protocol address.
    431  * Responses to the ARP request if the packet is the ARP request and is
    432  * targeted to my address.
    433  *
    434  * @param[in] device_id The source device identifier.
    435  * @param[in,out] packet The received packet.
    436  * @return              EOK on success and the packet is no longer needed.
    437  * @return              One on success and the packet has been reused.
    438  * @return              EINVAL if the packet is too small to carry an ARP
    439  *                      packet.
    440  * @return              EINVAL if the received address lengths differs from
    441  *                      the registered values.
    442  * @return              ENOENT if the device is not found in the cache.
    443  * @return              ENOENT if the protocol for the device is not found in
    444  *                      the cache.
    445  * @return              ENOMEM if there is not enough memory left.
    446  */
    447 static int arp_receive_message(device_id_t device_id, packet_t *packet)
    448 {
    449         size_t length;
    450         arp_header_t *header;
    451         arp_device_t *device;
    452         arp_proto_t *proto;
    453         arp_trans_t *trans;
    454         uint8_t *src_hw;
    455         uint8_t *src_proto;
    456         uint8_t *des_hw;
    457         uint8_t *des_proto;
    458         int rc;
    459        
    460         length = packet_get_data_length(packet);
     295       
     296        size_t length = packet_get_data_length(packet);
    461297        if (length <= sizeof(arp_header_t))
    462298                return EINVAL;
    463 
    464         device = arp_cache_find(&arp_globals.cache, device_id);
     299       
     300        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    465301        if (!device)
    466302                return ENOENT;
    467 
    468         header = (arp_header_t *) packet_get_data(packet);
     303       
     304        arp_header_t *header = (arp_header_t *) packet_get_data(packet);
    469305        if ((ntohs(header->hardware) != device->hardware) ||
    470306            (length < sizeof(arp_header_t) + header->hardware_length * 2U +
     
    472308                return EINVAL;
    473309        }
    474 
    475         proto = arp_protos_find(&device->protos,
     310       
     311        arp_proto_t *proto = arp_protos_find(&device->protos,
    476312            protocol_unmap(device->service, ntohs(header->protocol)));
    477313        if (!proto)
    478314                return ENOENT;
    479 
    480         src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
    481         src_proto = src_hw + header->hardware_length;
    482         des_hw = src_proto + header->protocol_length;
    483         des_proto = des_hw + header->hardware_length;
    484         trans = arp_addr_find(&proto->addresses, src_proto,
     315       
     316        uint8_t *src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
     317        uint8_t *src_proto = src_hw + header->hardware_length;
     318        uint8_t *des_hw = src_proto + header->protocol_length;
     319        uint8_t *des_proto = des_hw + header->hardware_length;
     320       
     321        arp_trans_t *trans = arp_addr_find(&proto->addresses, src_proto,
    485322            header->protocol_length);
    486         /* Exists? */
    487         if (trans && trans->hw_addr) {
     323       
     324        if ((trans) && (trans->hw_addr)) {
     325                /* Translation exists */
    488326                if (trans->hw_addr->length != header->hardware_length)
    489327                        return EINVAL;
     328               
    490329                memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
    491330        }
     331       
    492332        /* Is my protocol address? */
    493333        if (proto->addr->length != header->protocol_length)
     
    495335       
    496336        if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
    497                 /* Not already updated? */
    498337                if (!trans) {
     338                        /* Update the translation */
    499339                        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
    500340                        if (!trans)
    501341                                return ENOMEM;
     342                       
    502343                        trans->hw_addr = NULL;
    503344                        fibril_condvar_initialize(&trans->cv);
     
    509350                        }
    510351                }
     352               
    511353                if (!trans->hw_addr) {
    512354                        trans->hw_addr = measured_string_create_bulk(src_hw,
     
    518360                        fibril_condvar_broadcast(&trans->cv);
    519361                }
     362               
    520363                if (ntohs(header->operation) == ARPOP_REQUEST) {
    521364                        header->operation = htons(ARPOP_REPLY);
     
    538381                }
    539382        }
    540 
     383       
    541384        return EOK;
    542385}
    543386
    544 
    545 /** Returns the hardware address for the given protocol address.
    546  *
    547  * Sends the ARP request packet if the hardware address is not found in the
    548  * cache.
    549  *
    550  * @param[in] device_id The device identifier.
    551  * @param[in] protocol  The protocol service.
    552  * @param[in] target    The target protocol address.
    553  * @param[out] translation Where the hardware address of the target is stored.
    554  * @return              EOK on success.
    555  * @return              EAGAIN if the caller should try again.
    556  * @return              Other error codes in case of error.
    557  */
    558 static int
    559 arp_translate_message(device_id_t device_id, services_t protocol,
    560     measured_string_t *target, measured_string_t **translation)
    561 {
    562         arp_device_t *device;
    563         arp_proto_t *proto;
    564         arp_trans_t *trans;
    565         size_t length;
     387/** Update the device content length according to the new MTU value.
     388 *
     389 * @param[in] device_id Device identifier.
     390 * @param[in] mtu       New MTU value.
     391 *
     392 * @return ENOENT if device is not found.
     393 * @return EOK on success.
     394 *
     395 */
     396static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
     397{
     398        fibril_mutex_lock(&arp_globals.lock);
     399       
     400        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     401        if (!device) {
     402                fibril_mutex_unlock(&arp_globals.lock);
     403                return ENOENT;
     404        }
     405       
     406        device->packet_dimension.content = mtu;
     407       
     408        fibril_mutex_unlock(&arp_globals.lock);
     409       
     410        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
     411       
     412        return EOK;
     413}
     414
     415/** Process IPC messages from the registered device driver modules
     416 *
     417 * @param[in]     iid   Message identifier.
     418 * @param[in,out] icall Message parameters.
     419 *
     420 */
     421static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     422{
    566423        packet_t *packet;
    567         arp_header_t *header;
    568         bool retry = false;
    569424        int rc;
    570 
    571 restart:
    572         if (!target || !translation)
    573                 return EBADMEM;
    574 
    575         device = arp_cache_find(&arp_globals.cache, device_id);
    576         if (!device)
    577                 return ENOENT;
    578 
    579         proto = arp_protos_find(&device->protos, protocol);
    580         if (!proto || (proto->addr->length != target->length))
    581                 return ENOENT;
    582 
    583         trans = arp_addr_find(&proto->addresses, target->value, target->length);
    584         if (trans) {
    585                 if (trans->hw_addr) {
    586                         *translation = trans->hw_addr;
    587                         return EOK;
    588                 }
    589                 if (retry)
    590                         return EAGAIN;
    591                 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
    592                     ARP_TRANS_WAIT);
    593                 if (rc == ETIMEOUT)
     425       
     426        while (true) {
     427                switch (IPC_GET_IMETHOD(*icall)) {
     428                case NET_IL_DEVICE_STATE:
     429                        /* Do nothing - keep the cache */
     430                        ipc_answer_0(iid, (sysarg_t) EOK);
     431                        break;
     432               
     433                case NET_IL_RECEIVED:
     434                        rc = packet_translate_remote(arp_globals.net_phone, &packet,
     435                            IPC_GET_PACKET(*icall));
     436                        if (rc == EOK) {
     437                                fibril_mutex_lock(&arp_globals.lock);
     438                                do {
     439                                        packet_t *next = pq_detach(packet);
     440                                        rc = arp_receive_message(IPC_GET_DEVICE(*icall), packet);
     441                                        if (rc != 1) {
     442                                                pq_release_remote(arp_globals.net_phone,
     443                                                    packet_get_id(packet));
     444                                        }
     445                                       
     446                                        packet = next;
     447                                } while (packet);
     448                                fibril_mutex_unlock(&arp_globals.lock);
     449                        }
     450                        ipc_answer_0(iid, (sysarg_t) rc);
     451                        break;
     452               
     453                case NET_IL_MTU_CHANGED:
     454                        rc = arp_mtu_changed_message(IPC_GET_DEVICE(*icall),
     455                            IPC_GET_MTU(*icall));
     456                        ipc_answer_0(iid, (sysarg_t) rc);
     457                        break;
     458               
     459                default:
     460                        ipc_answer_0(iid, (sysarg_t) ENOTSUP);
     461                }
     462               
     463                iid = async_get_call(icall);
     464        }
     465}
     466
     467/** Register the device.
     468 *
     469 * Create new device entry in the cache or update the protocol address if the
     470 * device with the device identifier and the driver service exists.
     471 *
     472 * @param[in] device_id Device identifier.
     473 * @param[in] service   Device driver service.
     474 * @param[in] protocol  Protocol service.
     475 * @param[in] address   Actual device protocol address.
     476 *
     477 * @return EOK on success.
     478 * @return EEXIST if another device with the same device identifier
     479 *         and different driver service exists.
     480 * @return ENOMEM if there is not enough memory left.
     481 * @return Other error codes as defined for the
     482 *         measured_strings_return() function.
     483 *
     484 */
     485static int arp_device_message(device_id_t device_id, services_t service,
     486    services_t protocol, measured_string_t *address)
     487{
     488        int index;
     489        int rc;
     490       
     491        fibril_mutex_lock(&arp_globals.lock);
     492       
     493        /* An existing device? */
     494        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     495        if (device) {
     496                if (device->service != service) {
     497                        printf("%s: Device %d already exists\n", NAME,
     498                            device->device_id);
     499                        fibril_mutex_unlock(&arp_globals.lock);
     500                        return EEXIST;
     501                }
     502               
     503                arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
     504                if (proto) {
     505                        free(proto->addr);
     506                        free(proto->addr_data);
     507                        proto->addr = address;
     508                        proto->addr_data = address->value;
     509                } else {
     510                        rc = arp_proto_create(&proto, protocol, address);
     511                        if (rc != EOK) {
     512                                fibril_mutex_unlock(&arp_globals.lock);
     513                                return rc;
     514                        }
     515                       
     516                        index = arp_protos_add(&device->protos, proto->service,
     517                            proto);
     518                        if (index < 0) {
     519                                fibril_mutex_unlock(&arp_globals.lock);
     520                                free(proto);
     521                                return index;
     522                        }
     523                       
     524                        printf("%s: New protocol added (id: %d, proto: %d)\n", NAME,
     525                            device_id, protocol);
     526                }
     527        } else {
     528                hw_type_t hardware = hardware_map(service);
     529                if (!hardware)
    594530                        return ENOENT;
    595                 retry = true;
    596                 goto restart;
    597         }
    598         if (retry)
    599                 return EAGAIN;
    600 
     531               
     532                /* Create new device */
     533                device = (arp_device_t *) malloc(sizeof(arp_device_t));
     534                if (!device) {
     535                        fibril_mutex_unlock(&arp_globals.lock);
     536                        return ENOMEM;
     537                }
     538               
     539                device->hardware = hardware;
     540                device->device_id = device_id;
     541                rc = arp_protos_initialize(&device->protos);
     542                if (rc != EOK) {
     543                        fibril_mutex_unlock(&arp_globals.lock);
     544                        free(device);
     545                        return rc;
     546                }
     547               
     548                arp_proto_t *proto;
     549                rc = arp_proto_create(&proto, protocol, address);
     550                if (rc != EOK) {
     551                        fibril_mutex_unlock(&arp_globals.lock);
     552                        free(device);
     553                        return rc;
     554                }
     555               
     556                index = arp_protos_add(&device->protos, proto->service, proto);
     557                if (index < 0) {
     558                        fibril_mutex_unlock(&arp_globals.lock);
     559                        arp_protos_destroy(&device->protos);
     560                        free(device);
     561                        return index;
     562                }
     563               
     564                device->service = service;
     565               
     566                /* Bind */
     567                device->phone = nil_bind_service(device->service,
     568                    (sysarg_t) device->device_id, SERVICE_ARP,
     569                    arp_receiver);
     570                if (device->phone < 0) {
     571                        fibril_mutex_unlock(&arp_globals.lock);
     572                        arp_protos_destroy(&device->protos);
     573                        free(device);
     574                        return EREFUSED;
     575                }
     576               
     577                /* Get packet dimensions */
     578                rc = nil_packet_size_req(device->phone, device_id,
     579                    &device->packet_dimension);
     580                if (rc != EOK) {
     581                        fibril_mutex_unlock(&arp_globals.lock);
     582                        arp_protos_destroy(&device->protos);
     583                        free(device);
     584                        return rc;
     585                }
     586               
     587                /* Get hardware address */
     588                rc = nil_get_addr_req(device->phone, device_id, &device->addr,
     589                    &device->addr_data);
     590                if (rc != EOK) {
     591                        fibril_mutex_unlock(&arp_globals.lock);
     592                        arp_protos_destroy(&device->protos);
     593                        free(device);
     594                        return rc;
     595                }
     596               
     597                /* Get broadcast address */
     598                rc = nil_get_broadcast_addr_req(device->phone, device_id,
     599                    &device->broadcast_addr, &device->broadcast_data);
     600                if (rc != EOK) {
     601                        fibril_mutex_unlock(&arp_globals.lock);
     602                        free(device->addr);
     603                        free(device->addr_data);
     604                        arp_protos_destroy(&device->protos);
     605                        free(device);
     606                        return rc;
     607                }
     608               
     609                rc = arp_cache_add(&arp_globals.cache, device->device_id,
     610                    device);
     611                if (rc != EOK) {
     612                        fibril_mutex_unlock(&arp_globals.lock);
     613                        free(device->addr);
     614                        free(device->addr_data);
     615                        free(device->broadcast_addr);
     616                        free(device->broadcast_data);
     617                        arp_protos_destroy(&device->protos);
     618                        free(device);
     619                        return rc;
     620                }
     621                printf("%s: Device registered (id: %d, type: 0x%x, service: %d,"
     622                    " proto: %d)\n", NAME, device->device_id, device->hardware,
     623                    device->service, protocol);
     624        }
     625       
     626        fibril_mutex_unlock(&arp_globals.lock);
     627        return EOK;
     628}
     629
     630int il_initialize(int net_phone)
     631{
     632        fibril_mutex_initialize(&arp_globals.lock);
     633       
     634        fibril_mutex_lock(&arp_globals.lock);
     635        arp_globals.net_phone = net_phone;
     636        int rc = arp_cache_initialize(&arp_globals.cache);
     637        fibril_mutex_unlock(&arp_globals.lock);
     638       
     639        return rc;
     640}
     641
     642static int arp_send_request(device_id_t device_id, services_t protocol,
     643    measured_string_t *target, arp_device_t *device, arp_proto_t *proto)
     644{
    601645        /* ARP packet content size = header + (address + translation) * 2 */
    602         length = 8 + 2 * (proto->addr->length + device->addr->length);
     646        size_t length = 8 + 2 * (proto->addr->length + device->addr->length);
    603647        if (length > device->packet_dimension.content)
    604648                return ELIMIT;
    605 
    606         packet = packet_get_4_remote(arp_globals.net_phone,
     649       
     650        packet_t *packet = packet_get_4_remote(arp_globals.net_phone,
    607651            device->packet_dimension.addr_len, device->packet_dimension.prefix,
    608652            length, device->packet_dimension.suffix);
    609653        if (!packet)
    610654                return ENOMEM;
    611 
    612         header = (arp_header_t *) packet_suffix(packet, length);
     655       
     656        arp_header_t *header = (arp_header_t *) packet_suffix(packet, length);
    613657        if (!header) {
    614658                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    615659                return ENOMEM;
    616660        }
    617 
     661       
    618662        header->hardware = htons(device->hardware);
    619663        header->hardware_length = (uint8_t) device->addr->length;
     
    621665        header->protocol_length = (uint8_t) proto->addr->length;
    622666        header->operation = htons(ARPOP_REQUEST);
     667       
    623668        length = sizeof(arp_header_t);
     669       
    624670        memcpy(((uint8_t *) header) + length, device->addr->value,
    625671            device->addr->length);
     
    631677        length += device->addr->length;
    632678        memcpy(((uint8_t *) header) + length, target->value, target->length);
    633 
    634         rc = packet_set_addr(packet, (uint8_t *) device->addr->value,
     679       
     680        int rc = packet_set_addr(packet, (uint8_t *) device->addr->value,
    635681            (uint8_t *) device->broadcast_addr->value, device->addr->length);
    636682        if (rc != EOK) {
     
    638684                return rc;
    639685        }
    640 
     686       
    641687        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    642 
     688        return EOK;
     689}
     690
     691/** Return the hardware address for the given protocol address.
     692 *
     693 * Send the ARP request packet if the hardware address is not found in the
     694 * cache.
     695 *
     696 * @param[in]  device_id   Device identifier.
     697 * @param[in]  protocol    Protocol service.
     698 * @param[in]  target      Target protocol address.
     699 * @param[out] translation Where the hardware address of the target is stored.
     700 *
     701 * @return EOK on success.
     702 * @return EAGAIN if the caller should try again.
     703 * @return Other error codes in case of error.
     704 *
     705 */
     706static int arp_translate_message(device_id_t device_id, services_t protocol,
     707    measured_string_t *target, measured_string_t **translation)
     708{
     709        bool retry = false;
     710        int rc;
     711
     712        assert(fibril_mutex_is_locked(&arp_globals.lock));
     713       
     714restart:
     715        if ((!target) || (!translation))
     716                return EBADMEM;
     717       
     718        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     719        if (!device)
     720                return ENOENT;
     721       
     722        arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
     723        if ((!proto) || (proto->addr->length != target->length))
     724                return ENOENT;
     725       
     726        arp_trans_t *trans = arp_addr_find(&proto->addresses, target->value,
     727            target->length);
     728        if (trans) {
     729                if (trans->hw_addr) {
     730                        /* The translation is in place. */
     731                        *translation = trans->hw_addr;
     732                        return EOK;
     733                }
     734               
     735                if (retry) {
     736                        /*
     737                         * We may get here as a result of being signalled for
     738                         * some reason while waiting for the translation (e.g.
     739                         * translation becoming available, record being removed
     740                         * from the table) and then losing the race for
     741                         * the arp_globals.lock with someone else who modified
     742                         * the table.
     743                         *
     744                         * Remove the incomplete record so that it is possible
     745                         * to make new ARP requests.
     746                         */
     747                        arp_clear_trans(trans);
     748                        arp_addr_exclude(&proto->addresses, target->value,
     749                            target->length);
     750                        return EAGAIN;
     751                }
     752               
     753                /*
     754                 * We are a random passer-by who merely joins an already waiting
     755                 * fibril in waiting for the translation.
     756                 */
     757                rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
     758                    ARP_TRANS_WAIT);
     759                if (rc == ETIMEOUT)
     760                        return ENOENT;
     761               
     762                /*
     763                 * Need to recheck because we did not hold the lock while
     764                 * sleeping on the condition variable.
     765                 */
     766                retry = true;
     767                goto restart;
     768        }
     769       
     770        if (retry)
     771                return EAGAIN;
     772
     773        /*
     774         * We are under the protection of arp_globals.lock, so we can afford to
     775         * first send the ARP request and then insert an incomplete ARP record.
     776         * The incomplete record is used to tell any other potential waiter
     777         * that this fibril has already sent the request and that it is waiting
     778         * for the answer. Lastly, any fibril which sees the incomplete request
     779         * can perform a timed wait on its condition variable to wait for the
     780         * ARP reply to arrive.
     781         */
     782
     783        rc = arp_send_request(device_id, protocol, target, device, proto);
     784        if (rc != EOK)
     785                return rc;
     786       
    643787        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
    644788        if (!trans)
    645789                return ENOMEM;
     790       
    646791        trans->hw_addr = NULL;
    647792        fibril_condvar_initialize(&trans->cv);
     793       
    648794        rc = arp_addr_add(&proto->addresses, target->value, target->length,
    649795            trans);
     
    655801        rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
    656802            ARP_TRANS_WAIT);
    657         if (rc == ETIMEOUT)
     803        if (rc == ETIMEOUT) {
     804                /*
     805                 * Remove the incomplete record so that it is possible to make
     806                 * new ARP requests.
     807                 */
     808                arp_clear_trans(trans);
     809                arp_addr_exclude(&proto->addresses, target->value,
     810                    target->length);
    658811                return ENOENT;
     812        }
     813       
     814        /*
     815         * We need to recheck that the translation has indeed become available,
     816         * because we dropped the arp_globals.lock while sleeping on the
     817         * condition variable and someone else might have e.g. removed the
     818         * translation before we managed to lock arp_globals.lock again.
     819         */
     820
    659821        retry = true;
    660822        goto restart;
    661823}
    662824
    663 
    664 /** Processes the ARP message.
    665  *
    666  * @param[in] callid    The message identifier.
    667  * @param[in] call      The message parameters.
    668  * @param[out] answer   The message answer parameters.
    669  * @param[out] answer_count The last parameter for the actual answer in the
    670  *                      answer parameter.
    671  * @return              EOK on success.
    672  * @return              ENOTSUP if the message is not known.
     825/** Process the ARP message.
     826 *
     827 * @param[in]  callid Message identifier.
     828 * @param[in]  call   Message parameters.
     829 * @param[out] answer Answer.
     830 * @param[out] count  Number of arguments of the answer.
     831 *
     832 * @return EOK on success.
     833 * @return ENOTSUP if the message is not known.
    673834 *
    674835 * @see arp_interface.h
    675836 * @see IS_NET_ARP_MESSAGE()
    676  */
    677 int
    678 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    679     ipc_call_t *answer, size_t *answer_count)
     837 *
     838 */
     839int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     840    size_t *count)
    680841{
    681842        measured_string_t *address;
    682843        measured_string_t *translation;
    683844        uint8_t *data;
    684         packet_t *packet;
    685         packet_t *next;
    686845        int rc;
    687846       
    688         *answer_count = 0;
     847        *count = 0;
    689848        switch (IPC_GET_IMETHOD(*call)) {
    690849        case IPC_M_PHONE_HUNGUP:
     
    702861                        free(data);
    703862                }
     863               
    704864                return rc;
    705865       
     
    714874                free(address);
    715875                free(data);
     876               
    716877                if (rc != EOK) {
    717878                        fibril_mutex_unlock(&arp_globals.lock);
    718879                        return rc;
    719880                }
     881               
    720882                if (!translation) {
    721883                        fibril_mutex_unlock(&arp_globals.lock);
    722884                        return ENOENT;
    723885                }
     886               
    724887                rc = measured_strings_reply(translation, 1);
    725888                fibril_mutex_unlock(&arp_globals.lock);
    726889                return rc;
    727 
     890       
    728891        case NET_ARP_CLEAR_DEVICE:
    729892                return arp_clear_device_req(0, IPC_GET_DEVICE(*call));
    730 
     893       
    731894        case NET_ARP_CLEAR_ADDRESS:
    732895                rc = measured_strings_receive(&address, &data, 1);
     
    742905        case NET_ARP_CLEAN_CACHE:
    743906                return arp_clean_cache_req(0);
    744        
    745         case NET_IL_DEVICE_STATE:
    746                 /* Do nothing - keep the cache */
    747                 return EOK;
    748        
    749         case NET_IL_RECEIVED:
    750                
    751                 rc = packet_translate_remote(arp_globals.net_phone, &packet,
    752                     IPC_GET_PACKET(*call));
    753                 if (rc != EOK)
    754                         return rc;
    755                
    756                 fibril_mutex_lock(&arp_globals.lock);
    757                 do {
    758                         next = pq_detach(packet);
    759                         rc = arp_receive_message(IPC_GET_DEVICE(*call), packet);
    760                         if (rc != 1) {
    761                                 pq_release_remote(arp_globals.net_phone,
    762                                     packet_get_id(packet));
    763                         }
    764                         packet = next;
    765                 } while (packet);
    766                 fibril_mutex_unlock(&arp_globals.lock);
    767                
    768                 return EOK;
    769        
    770         case NET_IL_MTU_CHANGED:
    771                 return arp_mtu_changed_message(IPC_GET_DEVICE(*call),
    772                     IPC_GET_MTU(*call));
    773907        }
    774908       
     
    776910}
    777911
    778 /** Default thread for new connections.
    779  *
    780  * @param[in] iid       The initial message identifier.
    781  * @param[in] icall     The initial message call structure.
    782  */
    783 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    784 {
    785         /*
    786          * Accept the connection
    787          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    788          */
    789         ipc_answer_0(iid, EOK);
    790        
    791         while (true) {
    792                 ipc_call_t answer;
    793                 size_t count;
    794                
    795                 /* Clear the answer structure */
    796                 refresh_answer(&answer, &count);
    797                
    798                 /* Fetch the next message */
    799                 ipc_call_t call;
    800                 ipc_callid_t callid = async_get_call(&call);
    801                
    802                 /* Process the message */
    803                 int res = il_module_message_standalone(callid, &call, &answer,
    804                     &count);
    805                
    806                 /*
    807                  * End if told to either by the message or the processing
    808                  * result.
    809                  */
    810                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    811                     (res == EHANGUP))
    812                         return;
    813                
    814                 /* Answer the message */
    815                 answer_call(callid, res, &answer, count);
    816         }
    817 }
    818 
    819 /** Starts the module.
    820  *
    821  * @return              EOK on success.
    822  * @return              Other error codes as defined for each specific module
    823  *                      start function.
    824  */
    825912int main(int argc, char *argv[])
    826913{
    827         int rc;
    828        
    829914        /* Start the module */
    830         rc = il_module_start_standalone(il_client_connection);
    831         return rc;
     915        return il_module_start(SERVICE_ARP);
    832916}
    833917
    834918/** @}
    835919 */
    836 
  • uspace/srv/net/il/arp/arp.h

    r5ccb15c r60b2b69  
    125125        arp_cache_t cache;
    126126       
    127         /**
    128          * The client connection processing function.
    129          * The module skeleton propagates its own one.
    130          */
    131         async_client_conn_t client_connection;
    132        
    133127        /** Networking module phone. */
    134128        int net_phone;
  • uspace/srv/net/il/ip/Makefile

    r5ccb15c r60b2b69  
    3434
    3535SOURCES = \
    36         ip.c \
    37         ip_module.c
     36        ip.c
    3837
    3938include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/il/ip/ip.c

    r5ccb15c r60b2b69  
    3535 * @see arp.h
    3636 */
    37 
    38 #include "ip.h"
    39 #include "ip_module.h"
    4037
    4138#include <async.h>
     
    5249#include <sys/types.h>
    5350#include <byteorder.h>
     51#include "ip.h"
    5452
    5553#include <adt/measured_strings.h>
     
    7068#include <icmp_client.h>
    7169#include <icmp_interface.h>
    72 #include <il_interface.h>
    7370#include <ip_client.h>
    7471#include <ip_interface.h>
    7572#include <ip_header.h>
    7673#include <net_interface.h>
    77 #include <nil_interface.h>
    78 #include <tl_interface.h>
     74#include <nil_remote.h>
     75#include <tl_remote.h>
    7976#include <packet_remote.h>
    80 #include <il_local.h>
     77#include <il_remote.h>
     78#include <il_skel.h>
    8179
    8280/** IP module name. */
     
    122120INT_MAP_IMPLEMENT(ip_protos, ip_proto_t);
    123121GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t);
     122
     123static void ip_receiver(ipc_callid_t, ipc_call_t *);
    124124
    125125/** Releases the packet and returns the result.
     
    244244}
    245245
    246 /** Initializes the IP module.
    247  *
    248  * @param[in] client_connection The client connection processing function. The
    249  *                      module skeleton propagates its own one.
    250  * @return              EOK on success.
    251  * @return              ENOMEM if there is not enough memory left.
    252  */
    253 int ip_initialize(async_client_conn_t client_connection)
    254 {
    255         int rc;
    256 
     246int il_initialize(int net_phone)
     247{
    257248        fibril_rwlock_initialize(&ip_globals.lock);
    258249        fibril_rwlock_write_lock(&ip_globals.lock);
    259250        fibril_rwlock_initialize(&ip_globals.protos_lock);
    260251        fibril_rwlock_initialize(&ip_globals.netifs_lock);
     252       
     253        ip_globals.net_phone = net_phone;
    261254        ip_globals.packet_counter = 0;
    262255        ip_globals.gateway.address.s_addr = 0;
     
    264257        ip_globals.gateway.gateway.s_addr = 0;
    265258        ip_globals.gateway.netif = NULL;
    266         ip_globals.client_connection = client_connection;
    267        
    268         rc = ip_netifs_initialize(&ip_globals.netifs);
     259       
     260        int rc = ip_netifs_initialize(&ip_globals.netifs);
    269261        if (rc != EOK)
    270262                goto out;
     
    431423        ip_netif->phone = nil_bind_service(ip_netif->service,
    432424            (sysarg_t) ip_netif->device_id, SERVICE_IP,
    433             ip_globals.client_connection);
     425            ip_receiver);
    434426        if (ip_netif->phone < 0) {
    435427                printf("Failed to contact the nil service %d\n",
     
    487479}
    488480
    489 /** Updates the device content length according to the new MTU value.
    490  *
    491  * @param[in] device_id The device identifier.
    492  * @param[in] mtu       The new mtu value.
    493  * @return              EOK on success.
    494  * @return              ENOENT if device is not found.
    495  */
    496 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
    497 {
     481static int ip_device_req_local(int il_phone, device_id_t device_id,
     482    services_t netif)
     483{
     484        ip_netif_t *ip_netif;
     485        ip_route_t *route;
     486        int index;
     487        int rc;
     488
     489        ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t));
     490        if (!ip_netif)
     491                return ENOMEM;
     492
     493        rc = ip_routes_initialize(&ip_netif->routes);
     494        if (rc != EOK) {
     495                free(ip_netif);
     496                return rc;
     497        }
     498
     499        ip_netif->device_id = device_id;
     500        ip_netif->service = netif;
     501        ip_netif->state = NETIF_STOPPED;
     502
     503        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     504
     505        rc = ip_netif_initialize(ip_netif);
     506        if (rc != EOK) {
     507                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     508                ip_routes_destroy(&ip_netif->routes);
     509                free(ip_netif);
     510                return rc;
     511        }
     512        if (ip_netif->arp)
     513                ip_netif->arp->usage++;
     514
     515        // print the settings
     516        printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
     517            NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
     518            ip_netif->dhcp ? "dhcp" : "static");
     519       
     520        // TODO ipv6 addresses
     521       
     522        char address[INET_ADDRSTRLEN];
     523        char netmask[INET_ADDRSTRLEN];
     524        char gateway[INET_ADDRSTRLEN];
     525       
     526        for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) {
     527                route = ip_routes_get_index(&ip_netif->routes, index);
     528                if (route) {
     529                        inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr,
     530                            address, INET_ADDRSTRLEN);
     531                        inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr,
     532                            netmask, INET_ADDRSTRLEN);
     533                        inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr,
     534                            gateway, INET_ADDRSTRLEN);
     535                        printf("%s: Route %d (address: %s, netmask: %s, "
     536                            "gateway: %s)\n", NAME, index, address, netmask,
     537                            gateway);
     538                }
     539        }
     540       
     541        inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address,
     542            INET_ADDRSTRLEN);
     543        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     544
     545        printf("%s: Broadcast (%s)\n", NAME, address);
     546
     547        return EOK;
     548}
     549
     550/** Searches the network interfaces if there is a suitable route.
     551 *
     552 * @param[in] netif     The network interface to be searched for routes. May be
     553 *                      NULL.
     554 * @param[in] destination The destination address.
     555 * @return              The found route.
     556 * @return              NULL if no route was found.
     557 */
     558static ip_route_t *ip_netif_find_route(ip_netif_t *netif,
     559    in_addr_t destination)
     560{
     561        int index;
     562        ip_route_t *route;
     563       
     564        if (!netif)
     565                return NULL;
     566       
     567        /* Start with the first one (the direct route) */
     568        for (index = 0; index < ip_routes_count(&netif->routes); index++) {
     569                route = ip_routes_get_index(&netif->routes, index);
     570                if ((route) &&
     571                    ((route->address.s_addr & route->netmask.s_addr) ==
     572                    (destination.s_addr & route->netmask.s_addr)))
     573                        return route;
     574        }
     575
     576        return NULL;
     577}
     578
     579/** Searches all network interfaces if there is a suitable route.
     580 *
     581 * @param[in] destination The destination address.
     582 * @return              The found route.
     583 * @return              NULL if no route was found.
     584 */
     585static ip_route_t *ip_find_route(in_addr_t destination) {
     586        int index;
     587        ip_route_t *route;
    498588        ip_netif_t *netif;
    499589
    500         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    501         netif = ip_netifs_find(&ip_globals.netifs, device_id);
    502         if (!netif) {
    503                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    504                 return ENOENT;
    505         }
    506         netif->packet_dimension.content = mtu;
    507         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    508 
    509         printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
    510 
    511         return EOK;
    512 }
    513 
    514 /** Updates the device state.
    515  *
    516  * @param[in] device_id The device identifier.
    517  * @param[in] state     The new state value.
    518  * @return              EOK on success.
    519  * @return              ENOENT if device is not found.
    520  */
    521 static int ip_device_state_message(device_id_t device_id, device_state_t state)
    522 {
    523         ip_netif_t *netif;
    524 
    525         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    526         // find the device
    527         netif = ip_netifs_find(&ip_globals.netifs, device_id);
    528         if (!netif) {
    529                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    530                 return ENOENT;
    531         }
    532         netif->state = state;
    533         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    534 
    535         printf("%s: Device %d changed state to %d\n", NAME, device_id, state);
    536 
    537         return EOK;
    538 }
    539 
    540 
    541 /** Prefixes a middle fragment header based on the last fragment header to the
    542  * packet.
    543  *
    544  * @param[in] packet    The packet to be prefixed.
    545  * @param[in] last      The last header to be copied.
    546  * @return              The prefixed middle header.
    547  * @return              NULL on error.
    548  */
    549 static ip_header_t *
    550 ip_create_middle_header(packet_t *packet, ip_header_t *last)
    551 {
    552         ip_header_t *middle;
    553 
    554         middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));
    555         if (!middle)
    556                 return NULL;
    557         memcpy(middle, last, IP_HEADER_LENGTH(last));
    558         middle->flags |= IPFLAG_MORE_FRAGMENTS;
    559         return middle;
     590        // start with the last netif - the newest one
     591        index = ip_netifs_count(&ip_globals.netifs) - 1;
     592        while (index >= 0) {
     593                netif = ip_netifs_get_index(&ip_globals.netifs, index);
     594                if (netif && (netif->state == NETIF_ACTIVE)) {
     595                        route = ip_netif_find_route(netif, destination);
     596                        if (route)
     597                                return route;
     598                }
     599                index--;
     600        }
     601
     602        return &ip_globals.gateway;
     603}
     604
     605/** Returns the network interface's IP address.
     606 *
     607 * @param[in] netif     The network interface.
     608 * @return              The IP address.
     609 * @return              NULL if no IP address was found.
     610 */
     611static in_addr_t *ip_netif_address(ip_netif_t *netif)
     612{
     613        ip_route_t *route;
     614
     615        route = ip_routes_get_index(&netif->routes, 0);
     616        return route ? &route->address : NULL;
    560617}
    561618
     
    626683 *                      function.
    627684 */
    628 static int
    629 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet,
    630     measured_string_t *destination)
     685static int ip_prepare_packet(in_addr_t *source, in_addr_t dest,
     686    packet_t *packet, measured_string_t *destination)
    631687{
    632688        size_t length;
     
    757813 *                      function.
    758814 */
    759 static int
    760 ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
     815static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
    761816    ip_header_t *header, ip_header_t *new_header, size_t length,
    762817    const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen)
     
    792847
    793848        return pq_insert_after(packet, new_packet);
     849}
     850
     851/** Prefixes a middle fragment header based on the last fragment header to the
     852 * packet.
     853 *
     854 * @param[in] packet    The packet to be prefixed.
     855 * @param[in] last      The last header to be copied.
     856 * @return              The prefixed middle header.
     857 * @return              NULL on error.
     858 */
     859static ip_header_t *ip_create_middle_header(packet_t *packet,
     860    ip_header_t *last)
     861{
     862        ip_header_t *middle;
     863
     864        middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));
     865        if (!middle)
     866                return NULL;
     867        memcpy(middle, last, IP_HEADER_LENGTH(last));
     868        middle->flags |= IPFLAG_MORE_FRAGMENTS;
     869        return middle;
    794870}
    795871
     
    9961072 *                      function.
    9971073 */
    998 static int
    999 ip_send_route(packet_t *packet, ip_netif_t *netif, ip_route_t *route,
    1000     in_addr_t *src, in_addr_t dest, services_t error)
     1074static int ip_send_route(packet_t *packet, ip_netif_t *netif,
     1075    ip_route_t *route, in_addr_t *src, in_addr_t dest, services_t error)
    10011076{
    10021077        measured_string_t destination;
     
    10611136}
    10621137
    1063 /** Searches the network interfaces if there is a suitable route.
    1064  *
    1065  * @param[in] netif     The network interface to be searched for routes. May be
    1066  *                      NULL.
    1067  * @param[in] destination The destination address.
    1068  * @return              The found route.
    1069  * @return              NULL if no route was found.
    1070  */
    1071 static ip_route_t *
    1072 ip_netif_find_route(ip_netif_t *netif, in_addr_t destination)
    1073 {
    1074         int index;
    1075         ip_route_t *route;
    1076        
    1077         if (!netif)
    1078                 return NULL;
    1079        
    1080         /* Start with the first one (the direct route) */
    1081         for (index = 0; index < ip_routes_count(&netif->routes); index++) {
    1082                 route = ip_routes_get_index(&netif->routes, index);
    1083                 if ((route) &&
    1084                     ((route->address.s_addr & route->netmask.s_addr) ==
    1085                     (destination.s_addr & route->netmask.s_addr)))
    1086                         return route;
    1087         }
    1088 
    1089         return NULL;
    1090 }
    1091 
    1092 /** Searches all network interfaces if there is a suitable route.
    1093  *
    1094  * @param[in] destination The destination address.
    1095  * @return              The found route.
    1096  * @return              NULL if no route was found.
    1097  */
    1098 static ip_route_t *ip_find_route(in_addr_t destination) {
    1099         int index;
    1100         ip_route_t *route;
    1101         ip_netif_t *netif;
    1102 
    1103         // start with the last netif - the newest one
    1104         index = ip_netifs_count(&ip_globals.netifs) - 1;
    1105         while (index >= 0) {
    1106                 netif = ip_netifs_get_index(&ip_globals.netifs, index);
    1107                 if (netif && (netif->state == NETIF_ACTIVE)) {
    1108                         route = ip_netif_find_route(netif, destination);
    1109                         if (route)
    1110                                 return route;
    1111                 }
    1112                 index--;
    1113         }
    1114 
    1115         return &ip_globals.gateway;
    1116 }
    1117 
    1118 /** Returns the network interface's IP address.
    1119  *
    1120  * @param[in] netif     The network interface.
    1121  * @return              The IP address.
    1122  * @return              NULL if no IP address was found.
    1123  */
    1124 static in_addr_t *ip_netif_address(ip_netif_t *netif)
    1125 {
    1126         ip_route_t *route;
    1127 
    1128         route = ip_routes_get_index(&netif->routes, 0);
    1129         return route ? &route->address : NULL;
    1130 }
    1131 
    1132 /** Registers the transport layer protocol.
    1133  *
    1134  * The traffic of this protocol will be supplied using either the receive
    1135  * function or IPC message.
    1136  *
    1137  * @param[in] protocol  The transport layer module protocol.
    1138  * @param[in] service   The transport layer module service.
    1139  * @param[in] phone     The transport layer module phone.
    1140  * @param[in] received_msg The receiving function.
    1141  * @return              EOK on success.
    1142  * @return              EINVAL if the protocol parameter and/or the service
    1143  *                      parameter is zero.
    1144  * @return              EINVAL if the phone parameter is not a positive number
    1145  *                      and the tl_receive_msg is NULL.
    1146  * @return              ENOMEM if there is not enough memory left.
    1147  */
    1148 static int
    1149 ip_register(int protocol, services_t service, int phone,
    1150     tl_received_msg_t received_msg)
    1151 {
    1152         ip_proto_t *proto;
    1153         int index;
    1154 
    1155         if (!protocol || !service || ((phone < 0) && !received_msg))
    1156                 return EINVAL;
    1157 
    1158         proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
    1159         if (!proto)
    1160                 return ENOMEM;
    1161 
    1162         proto->protocol = protocol;
    1163         proto->service = service;
    1164         proto->phone = phone;
    1165         proto->received_msg = received_msg;
    1166 
    1167         fibril_rwlock_write_lock(&ip_globals.protos_lock);
    1168         index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
    1169         if (index < 0) {
    1170                 fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    1171                 free(proto);
    1172                 return index;
    1173         }
    1174         fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    1175 
    1176         printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
    1177             NAME, proto->protocol, proto->phone);
    1178 
    1179         return EOK;
    1180 }
    1181 
    1182 static int
    1183 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif)
    1184 {
    1185         ip_netif_t *ip_netif;
    1186         ip_route_t *route;
    1187         int index;
    1188         int rc;
    1189 
    1190         ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t));
    1191         if (!ip_netif)
    1192                 return ENOMEM;
    1193 
    1194         rc = ip_routes_initialize(&ip_netif->routes);
    1195         if (rc != EOK) {
    1196                 free(ip_netif);
    1197                 return rc;
    1198         }
    1199 
    1200         ip_netif->device_id = device_id;
    1201         ip_netif->service = netif;
    1202         ip_netif->state = NETIF_STOPPED;
    1203 
    1204         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    1205 
    1206         rc = ip_netif_initialize(ip_netif);
    1207         if (rc != EOK) {
    1208                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1209                 ip_routes_destroy(&ip_netif->routes);
    1210                 free(ip_netif);
    1211                 return rc;
    1212         }
    1213         if (ip_netif->arp)
    1214                 ip_netif->arp->usage++;
    1215 
    1216         // print the settings
    1217         printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
    1218             NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
    1219             ip_netif->dhcp ? "dhcp" : "static");
    1220        
    1221         // TODO ipv6 addresses
    1222        
    1223         char address[INET_ADDRSTRLEN];
    1224         char netmask[INET_ADDRSTRLEN];
    1225         char gateway[INET_ADDRSTRLEN];
    1226        
    1227         for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) {
    1228                 route = ip_routes_get_index(&ip_netif->routes, index);
    1229                 if (route) {
    1230                         inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr,
    1231                             address, INET_ADDRSTRLEN);
    1232                         inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr,
    1233                             netmask, INET_ADDRSTRLEN);
    1234                         inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr,
    1235                             gateway, INET_ADDRSTRLEN);
    1236                         printf("%s: Route %d (address: %s, netmask: %s, "
    1237                             "gateway: %s)\n", NAME, index, address, netmask,
    1238                             gateway);
    1239                 }
    1240         }
    1241        
    1242         inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address,
    1243             INET_ADDRSTRLEN);
    1244         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1245 
    1246         printf("%s: Broadcast (%s)\n", NAME, address);
    1247 
    1248         return EOK;
    1249 }
    1250 
    1251 static int
    1252 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet,
    1253     services_t sender, services_t error)
     1138static int ip_send_msg_local(int il_phone, device_id_t device_id,
     1139    packet_t *packet, services_t sender, services_t error)
    12541140{
    12551141        int addrlen;
     
    13551241}
    13561242
     1243/** Updates the device state.
     1244 *
     1245 * @param[in] device_id The device identifier.
     1246 * @param[in] state     The new state value.
     1247 * @return              EOK on success.
     1248 * @return              ENOENT if device is not found.
     1249 */
     1250static int ip_device_state_message(device_id_t device_id, device_state_t state)
     1251{
     1252        ip_netif_t *netif;
     1253
     1254        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     1255        // find the device
     1256        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1257        if (!netif) {
     1258                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1259                return ENOENT;
     1260        }
     1261        netif->state = state;
     1262        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1263
     1264        printf("%s: Device %d changed state to %d\n", NAME, device_id, state);
     1265
     1266        return EOK;
     1267}
     1268
     1269/** Returns the packet destination address from the IP header.
     1270 *
     1271 * @param[in] header    The packet IP header to be read.
     1272 * @return              The packet destination address.
     1273 */
     1274static in_addr_t ip_get_destination(ip_header_t *header)
     1275{
     1276        in_addr_t destination;
     1277
     1278        // TODO search set ipopt route?
     1279        destination.s_addr = header->destination_address;
     1280        return destination;
     1281}
     1282
     1283/** Delivers the packet to the local host.
     1284 *
     1285 * The packet is either passed to another module or released on error.
     1286 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not
     1287 * found.
     1288 *
     1289 * @param[in] device_id The source device identifier.
     1290 * @param[in] packet    The packet to be delivered.
     1291 * @param[in] header    The first packet IP header. May be NULL.
     1292 * @param[in] error     The packet error service.
     1293 * @return              EOK on success.
     1294 * @return              ENOTSUP if the packet is a fragment.
     1295 * @return              EAFNOSUPPORT if the address family is not supported.
     1296 * @return              ENOENT if the target protocol is not found.
     1297 * @return              Other error codes as defined for the packet_set_addr()
     1298 *                      function.
     1299 * @return              Other error codes as defined for the packet_trim()
     1300 *                      function.
     1301 * @return              Other error codes as defined for the protocol specific
     1302 *                      tl_received_msg() function.
     1303 */
     1304static int ip_deliver_local(device_id_t device_id, packet_t *packet,
     1305    ip_header_t *header, services_t error)
     1306{
     1307        ip_proto_t *proto;
     1308        int phone;
     1309        services_t service;
     1310        tl_received_msg_t received_msg;
     1311        struct sockaddr *src;
     1312        struct sockaddr *dest;
     1313        struct sockaddr_in src_in;
     1314        struct sockaddr_in dest_in;
     1315        socklen_t addrlen;
     1316        int rc;
     1317
     1318        if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
     1319            IP_FRAGMENT_OFFSET(header)) {
     1320                // TODO fragmented
     1321                return ENOTSUP;
     1322        }
     1323       
     1324        switch (header->version) {
     1325        case IPVERSION:
     1326                addrlen = sizeof(src_in);
     1327                bzero(&src_in, addrlen);
     1328                src_in.sin_family = AF_INET;
     1329                memcpy(&dest_in, &src_in, addrlen);
     1330                memcpy(&src_in.sin_addr.s_addr, &header->source_address,
     1331                    sizeof(header->source_address));
     1332                memcpy(&dest_in.sin_addr.s_addr, &header->destination_address,
     1333                    sizeof(header->destination_address));
     1334                src = (struct sockaddr *) &src_in;
     1335                dest = (struct sockaddr *) &dest_in;
     1336                break;
     1337
     1338        default:
     1339                return ip_release_and_return(packet, EAFNOSUPPORT);
     1340        }
     1341
     1342        rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest,
     1343            addrlen);
     1344        if (rc != EOK)
     1345                return ip_release_and_return(packet, rc);
     1346
     1347        // trim padding if present
     1348        if (!error &&
     1349            (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) {
     1350                rc = packet_trim(packet, 0,
     1351                    packet_get_data_length(packet) - IP_TOTAL_LENGTH(header));
     1352                if (rc != EOK)
     1353                        return ip_release_and_return(packet, rc);
     1354        }
     1355
     1356        fibril_rwlock_read_lock(&ip_globals.protos_lock);
     1357
     1358        proto = ip_protos_find(&ip_globals.protos, header->protocol);
     1359        if (!proto) {
     1360                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1361                phone = ip_prepare_icmp_and_get_phone(error, packet, header);
     1362                if (phone >= 0) {
     1363                        // unreachable ICMP
     1364                        icmp_destination_unreachable_msg(phone,
     1365                            ICMP_PROT_UNREACH, 0, packet);
     1366                }
     1367                return ENOENT;
     1368        }
     1369
     1370        if (proto->received_msg) {
     1371                service = proto->service;
     1372                received_msg = proto->received_msg;
     1373                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1374                rc = received_msg(device_id, packet, service, error);
     1375        } else {
     1376                rc = tl_received_msg(proto->phone, device_id, packet,
     1377                    proto->service, error);
     1378                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1379        }
     1380
     1381        return rc;
     1382}
     1383
     1384/** Processes the received packet.
     1385 *
     1386 * The packet is either passed to another module or released on error.
     1387 *
     1388 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is
     1389 * invalid.
     1390 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two.
     1391 * The ICMP_HOST_UNREACH error notification may be sent if no route was found.
     1392 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for
     1393 * another host and the routing is disabled.
     1394 *
     1395 * @param[in] device_id The source device identifier.
     1396 * @param[in] packet    The received packet to be processed.
     1397 * @return              EOK on success.
     1398 * @return              EINVAL if the TTL is less than two.
     1399 * @return              EINVAL if the checksum is invalid.
     1400 * @return              EAFNOSUPPORT if the address family is not supported.
     1401 * @return              ENOENT if no route was found.
     1402 * @return              ENOENT if the packet is for another host and the routing
     1403 *                      is disabled.
     1404 */
     1405static int ip_process_packet(device_id_t device_id, packet_t *packet)
     1406{
     1407        ip_header_t *header;
     1408        in_addr_t dest;
     1409        ip_route_t *route;
     1410        int phone;
     1411        struct sockaddr *addr;
     1412        struct sockaddr_in addr_in;
     1413        socklen_t addrlen;
     1414        int rc;
     1415       
     1416        header = (ip_header_t *) packet_get_data(packet);
     1417        if (!header)
     1418                return ip_release_and_return(packet, ENOMEM);
     1419
     1420        // checksum
     1421        if ((header->header_checksum) &&
     1422            (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
     1423                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1424                if (phone >= 0) {
     1425                        // checksum error ICMP
     1426                        icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
     1427                            ((size_t) ((void *) &header->header_checksum)) -
     1428                            ((size_t) ((void *) header)), packet);
     1429                }
     1430                return EINVAL;
     1431        }
     1432
     1433        if (header->ttl <= 1) {
     1434                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1435                if (phone >= 0) {
     1436                        // ttl exceeded ICMP
     1437                        icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
     1438                }
     1439                return EINVAL;
     1440        }
     1441       
     1442        // process ipopt and get destination
     1443        dest = ip_get_destination(header);
     1444
     1445        // set the addrination address
     1446        switch (header->version) {
     1447        case IPVERSION:
     1448                addrlen = sizeof(addr_in);
     1449                bzero(&addr_in, addrlen);
     1450                addr_in.sin_family = AF_INET;
     1451                memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest));
     1452                addr = (struct sockaddr *) &addr_in;
     1453                break;
     1454
     1455        default:
     1456                return ip_release_and_return(packet, EAFNOSUPPORT);
     1457        }
     1458
     1459        rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen);
     1460        if (rc != EOK)
     1461                return rc;
     1462       
     1463        route = ip_find_route(dest);
     1464        if (!route) {
     1465                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1466                if (phone >= 0) {
     1467                        // unreachable ICMP
     1468                        icmp_destination_unreachable_msg(phone,
     1469                            ICMP_HOST_UNREACH, 0, packet);
     1470                }
     1471                return ENOENT;
     1472        }
     1473
     1474        if (route->address.s_addr == dest.s_addr) {
     1475                // local delivery
     1476                return ip_deliver_local(device_id, packet, header, 0);
     1477        }
     1478
     1479        if (route->netif->routing) {
     1480                header->ttl--;
     1481                return ip_send_route(packet, route->netif, route, NULL, dest,
     1482                    0);
     1483        }
     1484
     1485        phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1486        if (phone >= 0) {
     1487                // unreachable ICMP if no routing
     1488                icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
     1489                    packet);
     1490        }
     1491       
     1492        return ENOENT;
     1493}
     1494
    13571495/** Returns the device packet dimensions for sending.
    13581496 *
     
    13661504 * @return              EOK on success.
    13671505 */
    1368 static int
    1369 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix,
    1370     size_t *content, size_t *suffix)
     1506static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,
     1507    size_t *prefix, size_t *content, size_t *suffix)
    13711508{
    13721509        ip_netif_t *netif;
     
    14181555}
    14191556
    1420 /** Returns the packet destination address from the IP header.
    1421  *
    1422  * @param[in] header    The packet IP header to be read.
    1423  * @return              The packet destination address.
    1424  */
    1425 static in_addr_t ip_get_destination(ip_header_t *header)
    1426 {
    1427         in_addr_t destination;
    1428 
    1429         // TODO search set ipopt route?
    1430         destination.s_addr = header->destination_address;
    1431         return destination;
    1432 }
    1433 
    1434 /** Delivers the packet to the local host.
    1435  *
    1436  * The packet is either passed to another module or released on error.
    1437  * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not
    1438  * found.
    1439  *
    1440  * @param[in] device_id The source device identifier.
    1441  * @param[in] packet    The packet to be delivered.
    1442  * @param[in] header    The first packet IP header. May be NULL.
    1443  * @param[in] error     The packet error service.
     1557/** Updates the device content length according to the new MTU value.
     1558 *
     1559 * @param[in] device_id The device identifier.
     1560 * @param[in] mtu       The new mtu value.
    14441561 * @return              EOK on success.
    1445  * @return              ENOTSUP if the packet is a fragment.
    1446  * @return              EAFNOSUPPORT if the address family is not supported.
    1447  * @return              ENOENT if the target protocol is not found.
    1448  * @return              Other error codes as defined for the packet_set_addr()
    1449  *                      function.
    1450  * @return              Other error codes as defined for the packet_trim()
    1451  *                      function.
    1452  * @return              Other error codes as defined for the protocol specific
    1453  *                      tl_received_msg() function.
     1562 * @return              ENOENT if device is not found.
     1563 */
     1564static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
     1565{
     1566        ip_netif_t *netif;
     1567
     1568        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     1569        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1570        if (!netif) {
     1571                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1572                return ENOENT;
     1573        }
     1574        netif->packet_dimension.content = mtu;
     1575        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1576
     1577        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
     1578
     1579        return EOK;
     1580}
     1581
     1582/** Process IPC messages from the registered device driver modules
     1583 *
     1584 * @param[in]     iid   Message identifier.
     1585 * @param[in,out] icall Message parameters.
     1586 *
     1587 */
     1588static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall)
     1589{
     1590        packet_t *packet;
     1591        int rc;
     1592       
     1593        while (true) {
     1594                switch (IPC_GET_IMETHOD(*icall)) {
     1595                case NET_IL_DEVICE_STATE:
     1596                        rc = ip_device_state_message(IPC_GET_DEVICE(*icall),
     1597                            IPC_GET_STATE(*icall));
     1598                        ipc_answer_0(iid, (sysarg_t) rc);
     1599                        break;
     1600               
     1601                case NET_IL_RECEIVED:
     1602                        rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1603                            IPC_GET_PACKET(*icall));
     1604                        if (rc == EOK) {
     1605                                do {
     1606                                        packet_t *next = pq_detach(packet);
     1607                                        ip_process_packet(IPC_GET_DEVICE(*icall), packet);
     1608                                        packet = next;
     1609                                } while (packet);
     1610                        }
     1611                       
     1612                        ipc_answer_0(iid, (sysarg_t) rc);
     1613                        break;
     1614               
     1615                case NET_IL_MTU_CHANGED:
     1616                        rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall),
     1617                            IPC_GET_MTU(*icall));
     1618                        ipc_answer_0(iid, (sysarg_t) rc);
     1619                        break;
     1620               
     1621                default:
     1622                        ipc_answer_0(iid, (sysarg_t) ENOTSUP);
     1623                }
     1624               
     1625                iid = async_get_call(icall);
     1626        }
     1627}
     1628
     1629/** Registers the transport layer protocol.
     1630 *
     1631 * The traffic of this protocol will be supplied using either the receive
     1632 * function or IPC message.
     1633 *
     1634 * @param[in] protocol  The transport layer module protocol.
     1635 * @param[in] service   The transport layer module service.
     1636 * @param[in] phone     The transport layer module phone.
     1637 * @param[in] received_msg The receiving function.
     1638 * @return              EOK on success.
     1639 * @return              EINVAL if the protocol parameter and/or the service
     1640 *                      parameter is zero.
     1641 * @return              EINVAL if the phone parameter is not a positive number
     1642 *                      and the tl_receive_msg is NULL.
     1643 * @return              ENOMEM if there is not enough memory left.
    14541644 */
    14551645static int
    1456 ip_deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header,
    1457     services_t error)
     1646ip_register(int protocol, services_t service, int phone,
     1647    tl_received_msg_t received_msg)
    14581648{
    14591649        ip_proto_t *proto;
    1460         int phone;
    1461         services_t service;
    1462         tl_received_msg_t received_msg;
    1463         struct sockaddr *src;
    1464         struct sockaddr *dest;
    1465         struct sockaddr_in src_in;
    1466         struct sockaddr_in dest_in;
    1467         socklen_t addrlen;
    1468         int rc;
    1469 
    1470         if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
    1471             IP_FRAGMENT_OFFSET(header)) {
    1472                 // TODO fragmented
    1473                 return ENOTSUP;
    1474         }
    1475        
    1476         switch (header->version) {
    1477         case IPVERSION:
    1478                 addrlen = sizeof(src_in);
    1479                 bzero(&src_in, addrlen);
    1480                 src_in.sin_family = AF_INET;
    1481                 memcpy(&dest_in, &src_in, addrlen);
    1482                 memcpy(&src_in.sin_addr.s_addr, &header->source_address,
    1483                     sizeof(header->source_address));
    1484                 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address,
    1485                     sizeof(header->destination_address));
    1486                 src = (struct sockaddr *) &src_in;
    1487                 dest = (struct sockaddr *) &dest_in;
    1488                 break;
    1489 
    1490         default:
    1491                 return ip_release_and_return(packet, EAFNOSUPPORT);
    1492         }
    1493 
    1494         rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest,
    1495             addrlen);
    1496         if (rc != EOK)
    1497                 return ip_release_and_return(packet, rc);
    1498 
    1499         // trim padding if present
    1500         if (!error &&
    1501             (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) {
    1502                 rc = packet_trim(packet, 0,
    1503                     packet_get_data_length(packet) - IP_TOTAL_LENGTH(header));
    1504                 if (rc != EOK)
    1505                         return ip_release_and_return(packet, rc);
    1506         }
    1507 
    1508         fibril_rwlock_read_lock(&ip_globals.protos_lock);
    1509 
    1510         proto = ip_protos_find(&ip_globals.protos, header->protocol);
    1511         if (!proto) {
    1512                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1513                 phone = ip_prepare_icmp_and_get_phone(error, packet, header);
    1514                 if (phone >= 0) {
    1515                         // unreachable ICMP
    1516                         icmp_destination_unreachable_msg(phone,
    1517                             ICMP_PROT_UNREACH, 0, packet);
    1518                 }
    1519                 return ENOENT;
    1520         }
    1521 
    1522         if (proto->received_msg) {
    1523                 service = proto->service;
    1524                 received_msg = proto->received_msg;
    1525                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1526                 rc = received_msg(device_id, packet, service, error);
    1527         } else {
    1528                 rc = tl_received_msg(proto->phone, device_id, packet,
    1529                     proto->service, error);
    1530                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1531         }
    1532 
    1533         return rc;
    1534 }
    1535 
    1536 /** Processes the received packet.
    1537  *
    1538  * The packet is either passed to another module or released on error.
    1539  *
    1540  * The ICMP_PARAM_POINTER error notification may be sent if the checksum is
    1541  * invalid.
    1542  * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two.
    1543  * The ICMP_HOST_UNREACH error notification may be sent if no route was found.
    1544  * The ICMP_HOST_UNREACH error notification may be sent if the packet is for
    1545  * another host and the routing is disabled.
    1546  *
    1547  * @param[in] device_id The source device identifier.
    1548  * @param[in] packet    The received packet to be processed.
    1549  * @return              EOK on success.
    1550  * @return              EINVAL if the TTL is less than two.
    1551  * @return              EINVAL if the checksum is invalid.
    1552  * @return              EAFNOSUPPORT if the address family is not supported.
    1553  * @return              ENOENT if no route was found.
    1554  * @return              ENOENT if the packet is for another host and the routing
    1555  *                      is disabled.
    1556  */
    1557 static int
    1558 ip_process_packet(device_id_t device_id, packet_t *packet)
    1559 {
    1560         ip_header_t *header;
    1561         in_addr_t dest;
    1562         ip_route_t *route;
    1563         int phone;
    1564         struct sockaddr *addr;
    1565         struct sockaddr_in addr_in;
    1566         socklen_t addrlen;
    1567         int rc;
    1568        
    1569         header = (ip_header_t *) packet_get_data(packet);
    1570         if (!header)
    1571                 return ip_release_and_return(packet, ENOMEM);
    1572 
    1573         // checksum
    1574         if ((header->header_checksum) &&
    1575             (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
    1576                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1577                 if (phone >= 0) {
    1578                         // checksum error ICMP
    1579                         icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
    1580                             ((size_t) ((void *) &header->header_checksum)) -
    1581                             ((size_t) ((void *) header)), packet);
    1582                 }
     1650        int index;
     1651
     1652        if (!protocol || !service || ((phone < 0) && !received_msg))
    15831653                return EINVAL;
    1584         }
    1585 
    1586         if (header->ttl <= 1) {
    1587                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1588                 if (phone >= 0) {
    1589                         // ttl exceeded ICMP
    1590                         icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
    1591                 }
    1592                 return EINVAL;
    1593         }
    1594        
    1595         // process ipopt and get destination
    1596         dest = ip_get_destination(header);
    1597 
    1598         // set the addrination address
    1599         switch (header->version) {
    1600         case IPVERSION:
    1601                 addrlen = sizeof(addr_in);
    1602                 bzero(&addr_in, addrlen);
    1603                 addr_in.sin_family = AF_INET;
    1604                 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest));
    1605                 addr = (struct sockaddr *) &addr_in;
    1606                 break;
    1607 
    1608         default:
    1609                 return ip_release_and_return(packet, EAFNOSUPPORT);
    1610         }
    1611 
    1612         rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen);
    1613         if (rc != EOK)
    1614                 return rc;
    1615        
    1616         route = ip_find_route(dest);
    1617         if (!route) {
    1618                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1619                 if (phone >= 0) {
    1620                         // unreachable ICMP
    1621                         icmp_destination_unreachable_msg(phone,
    1622                             ICMP_HOST_UNREACH, 0, packet);
    1623                 }
    1624                 return ENOENT;
    1625         }
    1626 
    1627         if (route->address.s_addr == dest.s_addr) {
    1628                 // local delivery
    1629                 return ip_deliver_local(device_id, packet, header, 0);
    1630         }
    1631 
    1632         if (route->netif->routing) {
    1633                 header->ttl--;
    1634                 return ip_send_route(packet, route->netif, route, NULL, dest,
    1635                     0);
    1636         }
    1637 
    1638         phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1639         if (phone >= 0) {
    1640                 // unreachable ICMP if no routing
    1641                 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
    1642                     packet);
    1643         }
    1644        
    1645         return ENOENT;
    1646 }
     1654
     1655        proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
     1656        if (!proto)
     1657                return ENOMEM;
     1658
     1659        proto->protocol = protocol;
     1660        proto->service = service;
     1661        proto->phone = phone;
     1662        proto->received_msg = received_msg;
     1663
     1664        fibril_rwlock_write_lock(&ip_globals.protos_lock);
     1665        index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
     1666        if (index < 0) {
     1667                fibril_rwlock_write_unlock(&ip_globals.protos_lock);
     1668                free(proto);
     1669                return index;
     1670        }
     1671        fibril_rwlock_write_unlock(&ip_globals.protos_lock);
     1672
     1673        printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
     1674            NAME, proto->protocol, proto->phone);
     1675
     1676        return EOK;
     1677}
     1678
    16471679
    16481680static int
     
    18451877}
    18461878
    1847 /** Processes the received IP packet or the packet queue one by one.
    1848  *
    1849  * The packet is either passed to another module or released on error.
    1850  *
    1851  * @param[in] device_id The source device identifier.
    1852  * @param[in,out] packet The received packet.
    1853  * @return              EOK on success and the packet is no longer needed.
    1854  * @return              EINVAL if the packet is too small to carry the IP
    1855  *                      packet.
    1856  * @return              EINVAL if the received address lengths differs from the
    1857  *                      registered values.
    1858  * @return              ENOENT if the device is not found in the cache.
    1859  * @return              ENOENT if the protocol for the device is not found in
    1860  *                      the cache.
    1861  * @return              ENOMEM if there is not enough memory left.
    1862  */
    1863 static int ip_receive_message(device_id_t device_id, packet_t *packet)
    1864 {
    1865         packet_t *next;
    1866 
    1867         do {
    1868                 next = pq_detach(packet);
    1869                 ip_process_packet(device_id, packet);
    1870                 packet = next;
    1871         } while (packet);
    1872 
    1873         return EOK;
    1874 }
    1875 
    18761879/** Processes the IP message.
    18771880 *
     
    18851888 *
    18861889 * @see ip_interface.h
    1887  * @see il_interface.h
     1890 * @see il_remote.h
    18881891 * @see IS_NET_IP_MESSAGE()
    18891892 */
    1890 int
    1891 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     1893int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    18921894    size_t *answer_count)
    18931895{
    18941896        packet_t *packet;
    18951897        struct sockaddr *addr;
     1898        void *header;
     1899        size_t headerlen;
    18961900        size_t addrlen;
    18971901        size_t prefix;
    18981902        size_t suffix;
    18991903        size_t content;
    1900         void *header;
    1901         size_t headerlen;
    19021904        device_id_t device_id;
    19031905        int rc;
     
    19121914                    IPC_GET_PHONE(*call), NULL);
    19131915       
    1914         case NET_IL_DEVICE:
     1916        case NET_IP_DEVICE:
    19151917                return ip_device_req_local(0, IPC_GET_DEVICE(*call),
    19161918                    IPC_GET_SERVICE(*call));
    1917        
    1918         case NET_IL_SEND:
    1919                 rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1920                     IPC_GET_PACKET(*call));
    1921                 if (rc != EOK)
    1922                         return rc;
    1923                 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
    1924                     IPC_GET_ERROR(*call));
    1925        
    1926         case NET_IL_DEVICE_STATE:
    1927                 return ip_device_state_message(IPC_GET_DEVICE(*call),
    1928                     IPC_GET_STATE(*call));
    1929        
    1930         case NET_IL_RECEIVED:
    1931                 rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1932                     IPC_GET_PACKET(*call));
    1933                 if (rc != EOK)
    1934                         return rc;
    1935                 return ip_receive_message(IPC_GET_DEVICE(*call), packet);
    19361919       
    19371920        case NET_IP_RECEIVED_ERROR:
     
    19751958                return rc;
    19761959       
    1977         case NET_IL_PACKET_SPACE:
     1960        case NET_IP_PACKET_SPACE:
    19781961                rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen,
    19791962                    &prefix, &content, &suffix);
     
    19881971                return EOK;
    19891972       
    1990         case NET_IL_MTU_CHANGED:
    1991                 return ip_mtu_changed_message(IPC_GET_DEVICE(*call),
    1992                     IPC_GET_MTU(*call));
     1973        case NET_IP_SEND:
     1974                rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1975                    IPC_GET_PACKET(*call));
     1976                if (rc != EOK)
     1977                        return rc;
     1978               
     1979                return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
     1980                    IPC_GET_ERROR(*call));
    19931981        }
    19941982       
     
    19961984}
    19971985
    1998 /** Default thread for new connections.
    1999  *
    2000  * @param[in] iid       The initial message identifier.
    2001  * @param[in] icall     The initial message call structure.
    2002  */
    2003 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    2004 {
    2005         /*
    2006          * Accept the connection
    2007          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    2008          */
    2009         ipc_answer_0(iid, EOK);
    2010        
    2011         while (true) {
    2012                 ipc_call_t answer;
    2013                 size_t count;
    2014                
    2015                 /* Clear the answer structure */
    2016                 refresh_answer(&answer, &count);
    2017                
    2018                 /* Fetch the next message */
    2019                 ipc_call_t call;
    2020                 ipc_callid_t callid = async_get_call(&call);
    2021                
    2022                 /* Process the message */
    2023                 int res = il_module_message_standalone(callid, &call, &answer,
    2024                     &count);
    2025                
    2026                 /*
    2027                  * End if told to either by the message or the processing
    2028                  * result.
    2029                  */
    2030                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    2031                     (res == EHANGUP)) {
    2032                         return;
    2033                 }
    2034                
    2035                 /* Answer the message */
    2036                 answer_call(callid, res, &answer, count);
    2037         }
    2038 }
    2039 
    2040 /** Starts the module.
    2041  *
    2042  * @return EOK on success.
    2043  * @return Other error codes as defined for each specific module start function.
    2044  */
    20451986int main(int argc, char *argv[])
    20461987{
    2047         int rc;
    2048        
    20491988        /* Start the module */
    2050         rc = il_module_start_standalone(il_client_connection);
    2051         return rc;
     1989        return il_module_start(SERVICE_IP);
    20521990}
    20531991
  • uspace/srv/net/il/ip/ip.h

    r5ccb15c r60b2b69  
    138138/** IP global data. */
    139139struct ip_globals {
    140         /** Default client connection function for support modules. */
    141         async_client_conn_t client_connection;
    142140        /** Default gateway. */
    143141        ip_route_t gateway;
  • uspace/srv/net/net/net.c

    r5ccb15c r60b2b69  
    4545#include <stdio.h>
    4646#include <str.h>
     47#include <str_error.h>
    4748
    4849#include <ipc/ipc.h>
     
    5152#include <ipc/net_net.h>
    5253#include <ipc/il.h>
     54#include <ipc/nil.h>
    5355
    5456#include <net/modules.h>
     
    6264
    6365#include <netif_remote.h>
    64 #include <nil_interface.h>
     66#include <nil_remote.h>
    6567#include <net_interface.h>
    6668#include <ip_interface.h>
     
    288290        if (rc != EOK)
    289291                return rc;
    290         rc = add_module(NULL, &net_globals.modules, (uint8_t *) DP8390_NAME,
    291             (uint8_t *) DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service);
     292        rc = add_module(NULL, &net_globals.modules, (uint8_t *) NE2000_NAME,
     293            (uint8_t *) NE2000_FILENAME, SERVICE_NE2000, 0, connect_to_service);
    292294        if (rc != EOK)
    293295                return rc;
     
    331333        if (rc != EOK)
    332334                return rc;
    333        
    334335       
    335336        rc = net_initialize(client_connection);
     
    591592                rc = start_device(netif);
    592593                if (rc != EOK) {
     594                        printf("%s: Error starting interface %s (%s)\n", NAME,
     595                            netif->name, str_error(rc));
    593596                        measured_strings_destroy(&netif->configuration);
    594597                        netifs_exclude_index(&net_globals.netifs, index);
     598                       
    595599                        return rc;
    596600                }
     
    709713int main(int argc, char *argv[])
    710714{
    711         int rc;
    712        
    713         rc = net_module_start(net_client_connection);
    714         if (rc != EOK) {
    715                 fprintf(stderr, "%s: net_module_start error %i\n", NAME, rc);
    716                 return rc;
    717         }
    718        
    719         return EOK;
     715        return net_module_start(net_client_connection);
    720716}
    721717
  • uspace/srv/net/net/net.h

    r5ccb15c r60b2b69  
    5252 */
    5353
    54 #define DP8390_FILENAME  "/srv/dp8390"
    55 #define DP8390_NAME      "dp8390"
     54#define NE2000_FILENAME  "/srv/ne2000"
     55#define NE2000_NAME      "ne2000"
    5656
    5757#define ETHERNET_FILENAME  "/srv/eth"
  • uspace/srv/net/netif/lo/lo.c

    r5ccb15c r60b2b69  
    4848#include <packet_client.h>
    4949#include <net/device.h>
    50 #include <nil_interface.h>
    5150#include <netif_skel.h>
    52 
    53 /** Default hardware address. */
    54 #define DEFAULT_ADDR  0
     51#include <nil_remote.h>
    5552
    5653/** Default address length. */
     
    6057#define NAME  "lo"
    6158
    62 /** Network interface global data. */
    63 netif_globals_t netif_globals;
     59static uint8_t default_addr[DEFAULT_ADDR_LEN] =
     60    {0, 0, 0, 0, 0, 0};
    6461
    6562int netif_specific_message(ipc_callid_t callid, ipc_call_t *call,
     
    7471                return EBADMEM;
    7572       
    76         uint8_t *addr = (uint8_t *) malloc(DEFAULT_ADDR_LEN);
    77         memset(addr, DEFAULT_ADDR, DEFAULT_ADDR_LEN);
    78        
    79         address->value = addr;
     73        address->value = default_addr;
    8074        address->length = DEFAULT_ADDR_LEN;
    8175       
     
    8579int netif_get_device_stats(device_id_t device_id, device_stats_t *stats)
    8680{
    87         netif_device_t *device;
    88         int rc;
    89 
    9081        if (!stats)
    9182                return EBADMEM;
    92 
    93         rc = find_device(device_id, &device);
     83       
     84        netif_device_t *device;
     85        int rc = find_device(device_id, &device);
    9486        if (rc != EOK)
    9587                return rc;
    96 
     88       
    9789        memcpy(stats, (device_stats_t *) device->specific,
    9890            sizeof(device_stats_t));
    99 
    100         return EOK;
    101 }
    102 
    103 /** Changes the loopback state.
    104  *
    105  * @param[in] device    The device structure.
    106  * @param[in] state     The new device state.
    107  * @return              The new state if changed.
    108  * @return              EOK otherwise.
    109  */
    110 static int change_state_message(netif_device_t *device, device_state_t state)
     91       
     92        return EOK;
     93}
     94
     95/** Change the loopback state.
     96 *
     97 * @param[in] device The device structure.
     98 * @param[in] state  The new device state.
     99 *
     100 * @return New state if changed.
     101 * @return EOK otherwise.
     102 *
     103 */
     104static void change_state_message(netif_device_t *device, device_state_t state)
    111105{
    112106        if (device->state != state) {
    113107                device->state = state;
    114108               
    115                 printf("%s: State changed to %s\n", NAME,
    116                     (state == NETIF_ACTIVE) ? "active" : "stopped");
     109                const char *desc;
     110                switch (state) {
     111                case NETIF_ACTIVE:
     112                        desc = "active";
     113                        break;
     114                case NETIF_STOPPED:
     115                        desc = "stopped";
     116                        break;
     117                default:
     118                        desc = "unknown";
     119                }
    117120               
    118                 return state;
    119         }
    120        
    121         return EOK;
    122 }
    123 
    124 /** Creates and returns the loopback network interface structure.
    125  *
    126  * @param[in] device_id The new devce identifier.
    127  * @param[out] device   The device structure.
    128  * @return              EOK on success.
    129  * @return              EXDEV if one loopback network interface already exists.
    130  * @return              ENOMEM if there is not enough memory left.
    131  */
    132 static int create(device_id_t device_id, netif_device_t **device)
    133 {
    134         int index;
    135 
     121                printf("%s: State changed to %s\n", NAME, desc);
     122        }
     123}
     124
     125/** Create and return the loopback network interface structure.
     126 *
     127 * @param[in]  device_id New devce identifier.
     128 * @param[out] device    Device structure.
     129 *
     130 * @return EOK on success.
     131 * @return EXDEV if one loopback network interface already exists.
     132 * @return ENOMEM if there is not enough memory left.
     133 *
     134 */
     135static int lo_create(device_id_t device_id, netif_device_t **device)
     136{
    136137        if (netif_device_map_count(&netif_globals.device_map) > 0)
    137138                return EXDEV;
    138 
     139       
    139140        *device = (netif_device_t *) malloc(sizeof(netif_device_t));
    140141        if (!*device)
    141142                return ENOMEM;
    142 
     143       
    143144        (*device)->specific = (device_stats_t *) malloc(sizeof(device_stats_t));
    144145        if (!(*device)->specific) {
     
    146147                return ENOMEM;
    147148        }
    148 
     149       
    149150        null_device_stats((device_stats_t *) (*device)->specific);
    150151        (*device)->device_id = device_id;
    151152        (*device)->nil_phone = -1;
    152153        (*device)->state = NETIF_STOPPED;
    153         index = netif_device_map_add(&netif_globals.device_map,
     154        int index = netif_device_map_add(&netif_globals.device_map,
    154155            (*device)->device_id, *device);
    155 
     156       
    156157        if (index < 0) {
    157158                free(*device);
     
    167168{
    168169        sysarg_t phonehash;
    169 
    170170        return ipc_connect_to_me(PHONE_NS, SERVICE_LO, 0, 0, &phonehash);
    171171}
     
    173173int netif_probe_message(device_id_t device_id, int irq, void *io)
    174174{
     175        /* Create a new device */
    175176        netif_device_t *device;
    176         int rc;
    177 
    178         /* Create a new device */
    179         rc = create(device_id, &device);
     177        int rc = lo_create(device_id, &device);
    180178        if (rc != EOK)
    181179                return rc;
    182 
    183         /* Print the settings */
     180       
    184181        printf("%s: Device created (id: %d)\n", NAME, device->device_id);
    185 
    186182        return EOK;
    187183}
     
    190186{
    191187        netif_device_t *device;
    192         size_t length;
    193         packet_t *next;
    194         int phone;
    195         int rc;
    196 
    197         rc = find_device(device_id, &device);
     188        int rc = find_device(device_id, &device);
    198189        if (rc != EOK)
    199190                return EOK;
    200 
     191       
    201192        if (device->state != NETIF_ACTIVE) {
    202193                netif_pq_release(packet_get_id(packet));
    203194                return EFORWARD;
    204195        }
    205 
    206         next = packet;
     196       
     197        packet_t *next = packet;
    207198        do {
    208199                ((device_stats_t *) device->specific)->send_packets++;
    209200                ((device_stats_t *) device->specific)->receive_packets++;
    210                 length = packet_get_data_length(next);
     201                size_t length = packet_get_data_length(next);
    211202                ((device_stats_t *) device->specific)->send_bytes += length;
    212203                ((device_stats_t *) device->specific)->receive_bytes += length;
    213204                next = pq_next(next);
    214         } while(next);
    215 
    216         phone = device->nil_phone;
     205        } while (next);
     206       
     207        int phone = device->nil_phone;
    217208        fibril_rwlock_write_unlock(&netif_globals.lock);
     209       
    218210        nil_received_msg(phone, device_id, packet, sender);
     211       
    219212        fibril_rwlock_write_lock(&netif_globals.lock);
    220        
    221213        return EOK;
    222214}
     
    224216int netif_start_message(netif_device_t *device)
    225217{
    226         return change_state_message(device, NETIF_ACTIVE);
     218        change_state_message(device, NETIF_ACTIVE);
     219        return device->state;
    227220}
    228221
    229222int netif_stop_message(netif_device_t *device)
    230223{
    231         return change_state_message(device, NETIF_STOPPED);
     224        change_state_message(device, NETIF_STOPPED);
     225        return device->state;
    232226}
    233227
  • uspace/srv/net/nil/eth/Makefile

    r5ccb15c r60b2b69  
    4242
    4343SOURCES = \
    44         eth.c \
    45         eth_module.c
     44        eth.c
    4645
    4746include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/nil/eth/eth.c

    r5ccb15c r60b2b69  
    4545
    4646#include <ipc/ipc.h>
     47#include <ipc/nil.h>
    4748#include <ipc/net.h>
    4849#include <ipc/services.h>
     
    5657#include <netif_remote.h>
    5758#include <net_interface.h>
    58 #include <nil_interface.h>
    59 #include <il_interface.h>
     59#include <il_remote.h>
    6060#include <adt/measured_strings.h>
    6161#include <packet_client.h>
    6262#include <packet_remote.h>
    63 #include <nil_local.h>
     63#include <nil_skel.h>
    6464
    6565#include "eth.h"
    66 #include "eth_header.h"
    6766
    6867/** The module name. */
     
    7271#define ETH_PREFIX \
    7372        (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \
    74         sizeof(eth_header_snap_t))
     73            sizeof(eth_header_snap_t))
    7574
    7675/** Reserved packet suffix length. */
    77 #define ETH_SUFFIX \
    78         sizeof(eth_fcs_t)
     76#define ETH_SUFFIX  (sizeof(eth_fcs_t))
    7977
    8078/** Maximum packet content length. */
    81 #define ETH_MAX_CONTENT 1500u
     79#define ETH_MAX_CONTENT  1500u
    8280
    8381/** Minimum packet content length. */
    84 #define ETH_MIN_CONTENT 46u
     82#define ETH_MIN_CONTENT  46u
    8583
    8684/** Maximum tagged packet content length. */
    8785#define ETH_MAX_TAGGED_CONTENT(flags) \
    8886        (ETH_MAX_CONTENT - \
    89         ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \
    90         sizeof(eth_header_lsap_t) : 0) - \
    91         (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
     87            ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \
     88            sizeof(eth_header_lsap_t) : 0) - \
     89            (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
    9290
    9391/** Minimum tagged packet content length. */
    9492#define ETH_MIN_TAGGED_CONTENT(flags) \
    9593        (ETH_MIN_CONTENT - \
    96         ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \
    97         sizeof(eth_header_lsap_t) : 0) - \
    98         (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
     94            ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \
     95            sizeof(eth_header_lsap_t) : 0) - \
     96            (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
    9997
    10098/** Dummy flag shift value. */
    101 #define ETH_DUMMY_SHIFT 0
     99#define ETH_DUMMY_SHIFT  0
    102100
    103101/** Mode flag shift value. */
    104 #define ETH_MODE_SHIFT  1
     102#define ETH_MODE_SHIFT  1
    105103
    106104/** Dummy device flag.
    107105 * Preamble and FCS are mandatory part of the packets.
    108106 */
    109 #define ETH_DUMMY               (1 << ETH_DUMMY_SHIFT)
     107#define ETH_DUMMY  (1 << ETH_DUMMY_SHIFT)
    110108
    111109/** Returns the dummy flag.
    112110 * @see ETH_DUMMY
    113111 */
    114 #define IS_DUMMY(flags)         ((flags) & ETH_DUMMY)
     112#define IS_DUMMY(flags)  ((flags) & ETH_DUMMY)
    115113
    116114/** Device mode flags.
     
    119117 * @see ETH_8023_2_SNAP
    120118 */
    121 #define ETH_MODE_MASK           (3 << ETH_MODE_SHIFT)
     119#define ETH_MODE_MASK  (3 << ETH_MODE_SHIFT)
    122120
    123121/** DIX Ethernet mode flag. */
    124 #define ETH_DIX                 (1 << ETH_MODE_SHIFT)
    125 
    126 /** Returns whether the DIX Ethernet mode flag is set.
    127  *
    128  * @param[in] flags     The ethernet flags.
     122#define ETH_DIX  (1 << ETH_MODE_SHIFT)
     123
     124/** Return whether the DIX Ethernet mode flag is set.
     125 *
     126 * @param[in] flags Ethernet flags.
    129127 * @see ETH_DIX
    130  */
    131 #define IS_DIX(flags)           (((flags) & ETH_MODE_MASK) == ETH_DIX)
     128 *
     129 */
     130#define IS_DIX(flags)  (((flags) & ETH_MODE_MASK) == ETH_DIX)
    132131
    133132/** 802.3 + 802.2 + LSAP mode flag. */
    134 #define ETH_8023_2_LSAP         (2 << ETH_MODE_SHIFT)
    135 
    136 /** Returns whether the 802.3 + 802.2 + LSAP mode flag is set.
    137  *
    138  * @param[in] flags     The ethernet flags.
     133#define ETH_8023_2_LSAP  (2 << ETH_MODE_SHIFT)
     134
     135/** Return whether the 802.3 + 802.2 + LSAP mode flag is set.
     136 *
     137 * @param[in] flags Ethernet flags.
    139138 * @see ETH_8023_2_LSAP
    140  */
    141 #define IS_8023_2_LSAP(flags)   (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP)
     139 *
     140 */
     141#define IS_8023_2_LSAP(flags)  (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP)
    142142
    143143/** 802.3 + 802.2 + LSAP + SNAP mode flag. */
    144 #define ETH_8023_2_SNAP         (3 << ETH_MODE_SHIFT)
    145 
    146 /** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.
    147  *
    148  * @param[in] flags     The ethernet flags.
     144#define ETH_8023_2_SNAP  (3 << ETH_MODE_SHIFT)
     145
     146/** Return whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.
     147 *
     148 * @param[in] flags Ethernet flags.
    149149 * @see ETH_8023_2_SNAP
    150  */
    151 #define IS_8023_2_SNAP(flags)   (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP)
     150 *
     151 */
     152#define IS_8023_2_SNAP(flags)  (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP)
    152153
    153154/** Type definition of the ethernet address type.
     
    246247                        rc = packet_translate_remote(eth_globals.net_phone,
    247248                            &packet, IPC_GET_PACKET(*icall));
    248                         if (rc == EOK) {
     249                        if (rc == EOK)
    249250                                rc = nil_received_msg_local(0,
    250251                                    IPC_GET_DEVICE(*icall), packet, 0);
    251                         }
     252                       
    252253                        ipc_answer_0(iid, (sysarg_t) rc);
    253254                        break;
     
    836837}
    837838
    838 int nil_message_standalone(const char *name, ipc_callid_t callid,
    839     ipc_call_t *call, ipc_call_t *answer, size_t *answer_count)
     839int nil_module_message(ipc_callid_t callid, ipc_call_t *call,
     840    ipc_call_t *answer, size_t *answer_count)
    840841{
    841842        measured_string_t *address;
     
    893894}
    894895
    895 /** Default thread for new connections.
    896  *
    897  * @param[in] iid       The initial message identifier.
    898  * @param[in] icall     The initial message call structure.
    899  */
    900 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    901 {
    902         /*
    903          * Accept the connection
    904          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    905          */
    906         ipc_answer_0(iid, EOK);
    907        
    908         while (true) {
    909                 ipc_call_t answer;
    910                 size_t count;
    911                
    912                 /* Clear the answer structure */
    913                 refresh_answer(&answer, &count);
    914                
    915                 /* Fetch the next message */
    916                 ipc_call_t call;
    917                 ipc_callid_t callid = async_get_call(&call);
    918                
    919                 /* Process the message */
    920                 int res = nil_module_message_standalone(NAME, callid, &call,
    921                     &answer, &count);
    922                
    923                 /*
    924                  * End if told to either by the message or the processing
    925                  * result.
    926                  */
    927                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    928                     (res == EHANGUP))
    929                         return;
    930                
    931                 /* Answer the message */
    932                 answer_call(callid, res, &answer, count);
    933         }
    934 }
    935 
    936896int main(int argc, char *argv[])
    937897{
    938         int rc;
    939        
    940898        /* Start the module */
    941         rc = nil_module_start_standalone(nil_client_connection);
    942         return rc;
     899        return nil_module_start(SERVICE_ETHERNET);
    943900}
    944901
  • uspace/srv/net/nil/eth/eth.h

    r5ccb15c r60b2b69  
    4444#include <adt/measured_strings.h>
    4545
     46/** Ethernet address length. */
     47#define ETH_ADDR  6
     48
     49/** Ethernet header preamble value. */
     50#define ETH_PREAMBLE  0x55
     51
     52/** Ethernet header start of frame value. */
     53#define ETH_SFD  0xD5
     54
     55/** IEEE 802.2 unordered information control field. */
     56#define IEEE_8023_2_UI  0x03
     57
     58/** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions.
     59 * @see eth_header_snap
     60 */
     61typedef struct eth_header_snap eth_header_snap_t;
     62
     63/** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions.
     64 * @see eth_header_lsap
     65 */
     66typedef struct eth_header_lsap eth_header_lsap_t;
     67
     68/** Type definition of the Ethernet header LSAP extension.
     69 * @see eth_ieee_lsap
     70 */
     71typedef struct eth_ieee_lsap eth_ieee_lsap_t;
     72
     73/** Type definition of the Ethernet header SNAP extension.
     74 * @see eth_snap
     75 */
     76typedef struct eth_snap eth_snap_t;
     77
     78/** Type definition of the Ethernet header preamble.
     79 * @see preamble
     80 */
     81typedef struct eth_preamble eth_preamble_t;
     82
     83/** Type definition of the Ethernet header.
     84 * @see eth_header
     85 */
     86typedef struct eth_header eth_header_t;
     87
     88/** Ethernet header Link Service Access Point extension. */
     89struct eth_ieee_lsap {
     90        /**
     91         * Destination Service Access Point identifier.
     92         * The possible values are assigned by an IEEE committee.
     93         */
     94        uint8_t dsap;
     95       
     96        /**
     97         * Source Service Access Point identifier.
     98         * The possible values are assigned by an IEEE committee.
     99         */
     100        uint8_t ssap;
     101       
     102        /**
     103         * Control parameter.
     104         * The possible values are assigned by an IEEE committee.
     105         */
     106        uint8_t ctrl;
     107} __attribute__ ((packed));
     108
     109/** Ethernet header SNAP extension. */
     110struct eth_snap {
     111        /** Protocol identifier or organization code. */
     112        uint8_t protocol[3];
     113       
     114        /**
     115         * Ethernet protocol identifier in the network byte order (big endian).
     116         * @see ethernet_protocols.h
     117         */
     118        uint16_t ethertype;
     119} __attribute__ ((packed));
     120
     121/** Ethernet header preamble.
     122 *
     123 * Used for dummy devices.
     124 */
     125struct eth_preamble {
     126        /**
     127         * Controlling preamble used for the frame transmission synchronization.
     128         * All should be set to ETH_PREAMBLE.
     129         */
     130        uint8_t preamble[7];
     131       
     132        /**
     133         * Start of Frame Delimiter used for the frame transmission
     134         * synchronization.
     135         * Should be set to ETH_SFD.
     136         */
     137        uint8_t sfd;
     138} __attribute__ ((packed));
     139
     140/** Ethernet header. */
     141struct eth_header {
     142        /** Destination host Ethernet address (MAC address). */
     143        uint8_t destination_address[ETH_ADDR];
     144        /** Source host Ethernet address (MAC address). */
     145        uint8_t source_address[ETH_ADDR];
     146       
     147        /**
     148         * Ethernet protocol identifier in the network byte order (big endian).
     149         * @see ethernet_protocols.h
     150         */
     151        uint16_t ethertype;
     152} __attribute__ ((packed));
     153
     154/** Ethernet header IEEE 802.3 + 802.2 extension. */
     155struct eth_header_lsap {
     156        /** Ethernet header. */
     157        eth_header_t header;
     158       
     159        /**
     160         * LSAP extension.
     161         * If DSAP and SSAP are set to ETH_LSAP_SNAP the SNAP extension is being
     162         * used.
     163         * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet
     164         * without any extensions is being used and the frame content starts
     165         * rigth after the two fields.
     166         */
     167        eth_ieee_lsap_t lsap;
     168} __attribute__ ((packed));
     169
     170/** Ethernet header IEEE 802.3 + 802.2 + SNAP extensions. */
     171struct eth_header_snap {
     172        /** Ethernet header. */
     173        eth_header_t header;
     174       
     175        /**
     176         * LSAP extension.
     177         * If DSAP and SSAP are set to ETH_LSAP_SNAP the SNAP extension is being
     178         * used.
     179         * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet
     180         * without any extensions is being used and the frame content starts
     181         * rigth after the two fields.
     182         */
     183        eth_ieee_lsap_t lsap;
     184       
     185        /** SNAP extension. */
     186        eth_snap_t snap;
     187} __attribute__ ((packed));
     188
     189/** Ethernet Frame Check Sequence. */
     190typedef uint32_t eth_fcs_t;
     191
    46192/** Type definition of the Ethernet global data.
    47193 * @see eth_globals
  • uspace/srv/net/nil/nildummy/Makefile

    r5ccb15c r60b2b69  
    4242
    4343SOURCES = \
    44         nildummy.c \
    45         nildummy_module.c
     44        nildummy.c
    4645
    4746include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/nil/nildummy/nildummy.c

    r5ccb15c r60b2b69  
    4242#include <str.h>
    4343#include <ipc/ipc.h>
     44#include <ipc/nil.h>
    4445#include <ipc/net.h>
    4546#include <ipc/services.h>
     
    4748#include <net/modules.h>
    4849#include <net/device.h>
    49 #include <nil_interface.h>
    50 #include <il_interface.h>
     50#include <il_remote.h>
    5151#include <adt/measured_strings.h>
    5252#include <net/packet.h>
    5353#include <packet_remote.h>
    5454#include <netif_remote.h>
    55 #include <nil_local.h>
     55#include <nil_skel.h>
    5656
    5757#include "nildummy.h"
     
    8181int nil_initialize(int net_phone)
    8282{
    83         int rc;
    84        
    8583        fibril_rwlock_initialize(&nildummy_globals.devices_lock);
    8684        fibril_rwlock_initialize(&nildummy_globals.protos_lock);
     
    9088        nildummy_globals.net_phone = net_phone;
    9189        nildummy_globals.proto.phone = 0;
    92         rc = nildummy_devices_initialize(&nildummy_globals.devices);
     90        int rc = nildummy_devices_initialize(&nildummy_globals.devices);
    9391       
    9492        fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
     
    9896}
    9997
    100 /** Process IPC messages from the registered device driver modules in an
    101  * infinite loop.
    102  *
    103  * @param[in] iid       The message identifier.
    104  * @param[in,out]       icall The message parameters.
     98/** Process IPC messages from the registered device driver modules
     99 *
     100 * @param[in]     iid   Message identifier.
     101 * @param[in,out] icall Message parameters.
     102 *
    105103 */
    106104static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall)
     
    108106        packet_t *packet;
    109107        int rc;
    110 
     108       
    111109        while (true) {
    112110                switch (IPC_GET_IMETHOD(*icall)) {
     
    120118                        rc = packet_translate_remote(nildummy_globals.net_phone,
    121119                            &packet, IPC_GET_PACKET(*icall));
    122                         if (rc == EOK) {
     120                        if (rc == EOK)
    123121                                rc = nil_received_msg_local(0,
    124122                                    IPC_GET_DEVICE(*icall), packet, 0);
    125                         }
     123                       
    126124                        ipc_answer_0(iid, (sysarg_t) rc);
    127125                        break;
     
    139137 * Determine the device local hardware address.
    140138 *
    141  * @param[in] device_id The new device identifier.
    142  * @param[in] service   The device driver service.
    143  * @param[in] mtu       The device maximum transmission unit.
    144  * @return              EOK on success.
    145  * @return              EEXIST if the device with the different service exists.
    146  * @return              ENOMEM if there is not enough memory left.
    147  * @return              Other error codes as defined for the
    148  *                      netif_bind_service() function.
    149  * @return              Other error codes as defined for the
    150  *                      netif_get_addr_req() function.
     139 * @param[in] device_id New device identifier.
     140 * @param[in] service   Device driver service.
     141 * @param[in] mtu       Device maximum transmission unit.
     142 *
     143 * @return EOK on success.
     144 * @return EEXIST if the device with the different service exists.
     145 * @return ENOMEM if there is not enough memory left.
     146 * @return Other error codes as defined for the
     147 *         netif_bind_service() function.
     148 * @return Other error codes as defined for the
     149 *         netif_get_addr_req() function.
     150 *
    151151 */
    152152static int nildummy_device_message(device_id_t device_id, services_t service,
    153153    size_t mtu)
    154154{
    155         nildummy_device_t *device;
    156         int index;
    157         int rc;
    158 
    159155        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
    160 
     156       
    161157        /* An existing device? */
    162         device = nildummy_devices_find(&nildummy_globals.devices, device_id);
     158        nildummy_device_t *device =
     159            nildummy_devices_find(&nildummy_globals.devices, device_id);
    163160        if (device) {
    164161                if (device->service != service) {
     
    213210       
    214211        /* Get hardware address */
    215         rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
    216             &device->addr_data);
     212        int rc = netif_get_addr_req(device->phone, device->device_id,
     213            &device->addr, &device->addr_data);
    217214        if (rc != EOK) {
    218215                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     
    222219       
    223220        /* Add to the cache */
    224         index = nildummy_devices_add(&nildummy_globals.devices,
     221        int index = nildummy_devices_add(&nildummy_globals.devices,
    225222            device->device_id, device);
    226223        if (index < 0) {
     
    240237/** Return the device hardware address.
    241238 *
    242  * @param[in] device_id The device identifier.
    243  * @param[out] address  The device hardware address.
    244  * @return               EOK on success.
    245  * @return              EBADMEM if the address parameter is NULL.
    246  * @return              ENOENT if there no such device.
     239 * @param[in]  device_id Device identifier.
     240 * @param[out] address   Device hardware address.
     241 *
     242 * @return EOK on success.
     243 * @return EBADMEM if the address parameter is NULL.
     244 * @return ENOENT if there no such device.
    247245 *
    248246 */
     
    250248    measured_string_t **address)
    251249{
    252         nildummy_device_t *device;
    253 
    254250        if (!address)
    255251                return EBADMEM;
    256252       
    257253        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    258         device = nildummy_devices_find(&nildummy_globals.devices, device_id);
     254       
     255        nildummy_device_t *device =
     256            nildummy_devices_find(&nildummy_globals.devices, device_id);
    259257        if (!device) {
    260258                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    261259                return ENOENT;
    262260        }
     261       
    263262        *address = device->addr;
     263       
    264264        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    265265       
     
    269269/** Return the device packet dimensions for sending.
    270270 *
    271  * @param[in] device_id The device identifier.
    272  * @param[out] addr_len The minimum reserved address length.
    273  * @param[out] prefix   The minimum reserved prefix size.
    274  * @param[out] content  The maximum content size.
    275  * @param[out] suffix   The minimum reserved suffix size.
    276  * @return              EOK on success.
    277  * @return              EBADMEM if either one of the parameters is NULL.
    278  * @return              ENOENT if there is no such device.
     271 * @param[in]  device_id Device identifier.
     272 * @param[out] addr_len  Minimum reserved address length.
     273 * @param[out] prefix    Minimum reserved prefix size.
     274 * @param[out] content   Maximum content size.
     275 * @param[out] suffix    Minimum reserved suffix size.
     276 *
     277 * @return EOK on success.
     278 * @return EBADMEM if either one of the parameters is NULL.
     279 * @return ENOENT if there is no such device.
    279280 *
    280281 */
     
    282283    size_t *prefix, size_t *content, size_t *suffix)
    283284{
    284         nildummy_device_t *device;
    285 
    286         if (!addr_len || !prefix || !content || !suffix)
     285        if ((!addr_len) || (!prefix) || (!content) || (!suffix))
    287286                return EBADMEM;
    288287       
    289288        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    290         device = nildummy_devices_find(&nildummy_globals.devices, device_id);
     289       
     290        nildummy_device_t *device =
     291            nildummy_devices_find(&nildummy_globals.devices, device_id);
    291292        if (!device) {
    292293                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    293294                return ENOENT;
    294295        }
    295 
     296       
    296297        *content = device->mtu;
     298       
    297299        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    298300       
     
    306308    packet_t *packet, services_t target)
    307309{
    308         packet_t *next;
    309 
    310310        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
     311       
    311312        if (nildummy_globals.proto.phone) {
    312313                do {
    313                         next = pq_detach(packet);
     314                        packet_t *next = pq_detach(packet);
    314315                        il_received_msg(nildummy_globals.proto.phone, device_id,
    315316                            packet, nildummy_globals.proto.service);
    316317                        packet = next;
    317                 } while(packet);
    318         }
     318                } while (packet);
     319        }
     320       
    319321        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    320322       
     
    326328 * Pass received packets for this service.
    327329 *
    328  * @param[in] service   The module service.
    329  * @param[in] phone     The service phone.
    330  * @return              EOK on success.
    331  * @return              ENOENT if the service is not known.
    332  * @return              ENOMEM if there is not enough memory left.
     330 * @param[in] service Module service.
     331 * @param[in] phone   Service phone.
     332 *
     333 * @return EOK on success.
     334 * @return ENOENT if the service is not known.
     335 * @return ENOMEM if there is not enough memory left.
     336 *
    333337 */
    334338static int nildummy_register_message(services_t service, int phone)
     
    347351/** Send the packet queue.
    348352 *
    349  * @param[in] device_id The device identifier.
    350  * @param[in] packet    The packet queue.
    351  * @param[in] sender    The sending module service.
    352  * @return              EOK on success.
    353  * @return              ENOENT if there no such device.
    354  * @return              EINVAL if the service parameter is not known.
     353 * @param[in] device_id Device identifier.
     354 * @param[in] packet    Packet queue.
     355 * @param[in] sender    Sending module service.
     356 *
     357 * @return EOK on success.
     358 * @return ENOENT if there no such device.
     359 * @return EINVAL if the service parameter is not known.
     360 *
    355361 */
    356362static int nildummy_send_message(device_id_t device_id, packet_t *packet,
    357363    services_t sender)
    358364{
    359         nildummy_device_t *device;
    360 
    361365        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    362         device = nildummy_devices_find(&nildummy_globals.devices, device_id);
     366       
     367        nildummy_device_t *device =
     368            nildummy_devices_find(&nildummy_globals.devices, device_id);
    363369        if (!device) {
    364370                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    365371                return ENOENT;
    366372        }
    367 
     373       
    368374        /* Send packet queue */
    369375        if (packet)
    370376                netif_send_msg(device->phone, device_id, packet,
    371377                    SERVICE_NILDUMMY);
     378       
    372379        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    373         return EOK;
    374 }
    375 
    376 int nil_message_standalone(const char *name, ipc_callid_t callid,
    377     ipc_call_t *call, ipc_call_t *answer, size_t *answer_count)
     380       
     381        return EOK;
     382}
     383
     384int nil_module_message(ipc_callid_t callid, ipc_call_t *call,
     385    ipc_call_t *answer, size_t *answer_count)
    378386{
    379387        measured_string_t *address;
     
    434442}
    435443
    436 /** Default thread for new connections.
    437  *
    438  * @param[in] iid       The initial message identifier.
    439  * @param[in] icall     The initial message call structure.
    440  */
    441 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    442 {
    443         /*
    444          * Accept the connection
    445          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    446          */
    447         ipc_answer_0(iid, EOK);
    448        
    449         while (true) {
    450                 ipc_call_t answer;
    451                 size_t count;
    452                
    453                 /* Clear the answer structure */
    454                 refresh_answer(&answer, &count);
    455                
    456                 /* Fetch the next message */
    457                 ipc_call_t call;
    458                 ipc_callid_t callid = async_get_call(&call);
    459                
    460                 /* Process the message */
    461                 int res = nil_module_message_standalone(NAME, callid, &call,
    462                     &answer, &count);
    463                
    464                 /*
    465                  * End if told to either by the message or the processing
    466                  * result.
    467                  */
    468                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    469                     (res == EHANGUP))
    470                         return;
    471                
    472                 /* Answer the message */
    473                 answer_call(callid, res, &answer, count);
    474         }
    475 }
    476 
    477444int main(int argc, char *argv[])
    478445{
    479         int rc;
    480        
    481446        /* Start the module */
    482         rc = nil_module_start_standalone(nil_client_connection);
    483         return rc;
     447        return nil_module_start(SERVICE_NILDUMMY);
    484448}
    485449
  • uspace/srv/net/nil/nildummy/nildummy.h

    r5ccb15c r60b2b69  
    4545
    4646/** Type definition of the dummy nil global data.
     47 *
    4748 * @see nildummy_globals
     49 *
    4850 */
    4951typedef struct nildummy_globals nildummy_globals_t;
    5052
    5153/** Type definition of the dummy nil device specific data.
     54 *
    5255 * @see nildummy_device
     56 *
    5357 */
    5458typedef struct nildummy_device nildummy_device_t;
    5559
    5660/** Type definition of the dummy nil protocol specific data.
     61 *
    5762 * @see nildummy_proto
     63 *
    5864 */
    5965typedef struct nildummy_proto nildummy_proto_t;
    6066
    6167/** Dummy nil device map.
    62  * Maps devices to the dummy nil device specific data.
     68 *
     69 * Map devices to the dummy nil device specific data.
    6370 * @see device.h
     71 *
    6472 */
    6573DEVICE_MAP_DECLARE(nildummy_devices, nildummy_device_t);
     
    6977        /** Device identifier. */
    7078        device_id_t device_id;
     79       
    7180        /** Device driver service. */
    7281        services_t service;
     82       
    7383        /** Driver phone. */
    7484        int phone;
     85       
    7586        /** Maximal transmission unit. */
    7687        size_t mtu;
     88       
    7789        /** Actual device hardware address. */
    7890        measured_string_t *addr;
     91       
    7992        /** Actual device hardware address data. */
    8093        uint8_t *addr_data;
     
    8598        /** Protocol service. */
    8699        services_t service;
     100       
    87101        /** Protocol module phone. */
    88102        int phone;
     
    93107        /** Networking module phone. */
    94108        int net_phone;
    95         /** Safety lock for devices. */
     109       
     110        /** Lock for devices. */
    96111        fibril_rwlock_t devices_lock;
     112       
    97113        /** All known Ethernet devices. */
    98114        nildummy_devices_t devices;
     115       
    99116        /** Safety lock for protocols. */
    100117        fibril_rwlock_t protos_lock;
     118       
    101119        /** Default protocol. */
    102120        nildummy_proto_t proto;
  • uspace/srv/net/tl/icmp/Makefile

    r5ccb15c r60b2b69  
    3434
    3535SOURCES = \
    36         icmp.c \
    37         icmp_module.c
     36        icmp.c
    3837
    3938include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/tl/icmp/icmp.c

    r5ccb15c r60b2b69  
    3535 * @see icmp.h
    3636 */
    37 
    38 #include "icmp.h"
    39 #include "icmp_module.h"
    4037
    4138#include <async.h>
     
    6865#include <icmp_client.h>
    6966#include <icmp_interface.h>
    70 #include <il_interface.h>
     67#include <il_remote.h>
    7168#include <ip_client.h>
    7269#include <ip_interface.h>
    7370#include <net_interface.h>
    74 #include <tl_interface.h>
    75 #include <tl_local.h>
     71#include <tl_remote.h>
     72#include <tl_skel.h>
    7673#include <icmp_header.h>
    7774
     75#include "icmp.h"
     76
    7877/** ICMP module name. */
    79 #define NAME    "ICMP protocol"
     78#define NAME  "icmp"
    8079
    8180/** Default ICMP error reporting. */
     
    394393}
    395394
    396 /** Initializes the ICMP module.
    397  *
    398  * @param[in] client_connection The client connection processing function. The
    399  *                      module skeleton propagates its own one.
    400  * @return              EOK on success.
    401  * @return              ENOMEM if there is not enough memory left.
    402  */
    403 int icmp_initialize(async_client_conn_t client_connection)
    404 {
    405         measured_string_t names[] = {
    406                 {
    407                         (uint8_t *) "ICMP_ERROR_REPORTING",
    408                         20
    409                 },
    410                 {
    411                         (uint8_t *) "ICMP_ECHO_REPLYING",
    412                         18
    413                 }
    414         };
    415         measured_string_t *configuration;
    416         size_t count = sizeof(names) / sizeof(measured_string_t);
    417         uint8_t *data;
    418         int rc;
    419 
    420         fibril_rwlock_initialize(&icmp_globals.lock);
    421         fibril_rwlock_write_lock(&icmp_globals.lock);
    422         icmp_replies_initialize(&icmp_globals.replies);
    423         icmp_echo_data_initialize(&icmp_globals.echo_data);
    424        
    425         icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP,
    426             SERVICE_ICMP, client_connection);
    427         if (icmp_globals.ip_phone < 0) {
    428                 fibril_rwlock_write_unlock(&icmp_globals.lock);
    429                 return icmp_globals.ip_phone;
    430         }
    431        
    432         rc = ip_packet_size_req(icmp_globals.ip_phone, -1,
    433             &icmp_globals.packet_dimension);
    434         if (rc != EOK) {
    435                 fibril_rwlock_write_unlock(&icmp_globals.lock);
    436                 return rc;
    437         }
    438 
    439         icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE;
    440         icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE;
    441 
    442         icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING;
    443         icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING;
    444 
    445         /* Get configuration */
    446         configuration = &names[0];
    447         rc = net_get_conf_req(icmp_globals.net_phone, &configuration, count,
    448             &data);
    449         if (rc != EOK) {
    450                 fibril_rwlock_write_unlock(&icmp_globals.lock);
    451                 return rc;
    452         }
    453        
    454         if (configuration) {
    455                 if (configuration[0].value) {
    456                         icmp_globals.error_reporting =
    457                             (configuration[0].value[0] == 'y');
    458                 }
    459                 if (configuration[1].value) {
    460                         icmp_globals.echo_replying =
    461                             (configuration[1].value[0] == 'y');
    462                 }
    463                 net_free_settings(configuration, data);
    464         }
    465 
    466         fibril_rwlock_write_unlock(&icmp_globals.lock);
    467         return EOK;
    468 }
    469 
    470395/** Tries to set the pending reply result as the received message type.
    471396 *
     
    667592                return icmp_release_and_return(packet, rc);
    668593
     594        return EOK;
     595}
     596
     597/** Process IPC messages from the IP module
     598 *
     599 * @param[in]     iid   Message identifier.
     600 * @param[in,out] icall Message parameters.
     601 *
     602 */
     603static void icmp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     604{
     605        packet_t *packet;
     606        int rc;
     607       
     608        while (true) {
     609                switch (IPC_GET_IMETHOD(*icall)) {
     610                case NET_TL_RECEIVED:
     611                        rc = packet_translate_remote(icmp_globals.net_phone, &packet,
     612                            IPC_GET_PACKET(*icall));
     613                        if (rc == EOK)
     614                                rc = icmp_received_msg_local(IPC_GET_DEVICE(*icall), packet,
     615                                    SERVICE_ICMP, IPC_GET_ERROR(*icall));
     616                       
     617                        ipc_answer_0(iid, (sysarg_t) rc);
     618                        break;
     619                default:
     620                        ipc_answer_0(iid, (sysarg_t) ENOTSUP);
     621                }
     622               
     623                iid = async_get_call(icall);
     624        }
     625}
     626
     627/** Initialize the ICMP module.
     628 *
     629 * @param[in] net_phone Network module phone.
     630 *
     631 * @return EOK on success.
     632 * @return ENOMEM if there is not enough memory left.
     633 *
     634 */
     635int tl_initialize(int net_phone)
     636{
     637        measured_string_t names[] = {
     638                {
     639                        (uint8_t *) "ICMP_ERROR_REPORTING",
     640                        20
     641                },
     642                {
     643                        (uint8_t *) "ICMP_ECHO_REPLYING",
     644                        18
     645                }
     646        };
     647        measured_string_t *configuration;
     648        size_t count = sizeof(names) / sizeof(measured_string_t);
     649        uint8_t *data;
     650       
     651        fibril_rwlock_initialize(&icmp_globals.lock);
     652        fibril_rwlock_write_lock(&icmp_globals.lock);
     653        icmp_replies_initialize(&icmp_globals.replies);
     654        icmp_echo_data_initialize(&icmp_globals.echo_data);
     655       
     656        icmp_globals.net_phone = net_phone;
     657       
     658        icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP,
     659            SERVICE_ICMP, icmp_receiver);
     660        if (icmp_globals.ip_phone < 0) {
     661                fibril_rwlock_write_unlock(&icmp_globals.lock);
     662                return icmp_globals.ip_phone;
     663        }
     664       
     665        int rc = ip_packet_size_req(icmp_globals.ip_phone, -1,
     666            &icmp_globals.packet_dimension);
     667        if (rc != EOK) {
     668                fibril_rwlock_write_unlock(&icmp_globals.lock);
     669                return rc;
     670        }
     671       
     672        icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE;
     673        icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE;
     674       
     675        icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING;
     676        icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING;
     677       
     678        /* Get configuration */
     679        configuration = &names[0];
     680        rc = net_get_conf_req(icmp_globals.net_phone, &configuration, count,
     681            &data);
     682        if (rc != EOK) {
     683                fibril_rwlock_write_unlock(&icmp_globals.lock);
     684                return rc;
     685        }
     686       
     687        if (configuration) {
     688                if (configuration[0].value) {
     689                        icmp_globals.error_reporting =
     690                            (configuration[0].value[0] == 'y');
     691                }
     692                if (configuration[1].value) {
     693                        icmp_globals.echo_replying =
     694                            (configuration[1].value[0] == 'y');
     695                }
     696                net_free_settings(configuration, data);
     697        }
     698       
     699        fibril_rwlock_write_unlock(&icmp_globals.lock);
    669700        return EOK;
    670701}
     
    893924 * @see IS_NET_ICMP_MESSAGE()
    894925 */
    895 int icmp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     926int tl_module_message   (ipc_callid_t callid, ipc_call_t *call,
    896927    ipc_call_t *answer, size_t *answer_count)
    897928{
    898         packet_t *packet;
    899         int rc;
    900 
    901929        *answer_count = 0;
    902930        switch (IPC_GET_IMETHOD(*call)) {
    903         case NET_TL_RECEIVED:
    904                 rc = packet_translate_remote(icmp_globals.net_phone, &packet,
    905                     IPC_GET_PACKET(*call));
    906                 if (rc != EOK)
    907                         return rc;
    908                 return icmp_received_msg_local(IPC_GET_DEVICE(*call), packet,
    909                     SERVICE_ICMP, IPC_GET_ERROR(*call));
    910        
    911931        case NET_ICMP_INIT:
    912932                return icmp_process_client_messages(callid, *call);
    913        
    914933        default:
    915934                return icmp_process_message(call);
    916935        }
    917 
     936       
    918937        return ENOTSUP;
    919938}
    920939
    921 
    922 /** Default thread for new connections.
    923  *
    924  * @param[in] iid The initial message identifier.
    925  * @param[in] icall The initial message call structure.
    926  *
    927  */
    928 static void tl_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    929 {
    930         /*
    931          * Accept the connection
    932          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    933          */
    934         ipc_answer_0(iid, EOK);
    935        
    936         while (true) {
    937                 ipc_call_t answer;
    938                 size_t answer_count;
    939                
    940                 /* Clear the answer structure */
    941                 refresh_answer(&answer, &answer_count);
    942                
    943                 /* Fetch the next message */
    944                 ipc_call_t call;
    945                 ipc_callid_t callid = async_get_call(&call);
    946                
    947                 /* Process the message */
    948                 int res = tl_module_message_standalone(callid, &call, &answer,
    949                     &answer_count);
    950                
    951                 /*
    952                  * End if told to either by the message or the processing
    953                  * result.
    954                  */
    955                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    956                     (res == EHANGUP))
    957                         return;
    958                
    959                 /* Answer the message */
    960                 answer_call(callid, res, &answer, answer_count);
    961         }
    962 }
    963 
    964 /** Starts the module.
    965  *
    966  * @return              EOK on success.
    967  * @return              Other error codes as defined for each specific module
    968  *                      start function.
    969  */
    970940int main(int argc, char *argv[])
    971941{
    972         int rc;
    973        
    974942        /* Start the module */
    975         rc = tl_module_start_standalone(tl_client_connection);
    976         return rc;
     943        return tl_module_start(SERVICE_ICMP);
    977944}
    978945
    979946/** @}
    980947 */
    981 
  • uspace/srv/net/tl/tcp/Makefile

    r5ccb15c r60b2b69  
    3434
    3535SOURCES = \
    36         tcp.c \
    37         tcp_module.c
     36        tcp.c
    3837
    3938include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/tl/tcp/tcp.c

    r5ccb15c r60b2b69  
    3636 */
    3737
    38 #include "tcp.h"
    39 #include "tcp_header.h"
    40 #include "tcp_module.h"
    41 
    4238#include <assert.h>
    4339#include <async.h>
     
    7268#include <socket_core.h>
    7369#include <tl_common.h>
    74 #include <tl_local.h>
    75 #include <tl_interface.h>
     70#include <tl_remote.h>
     71#include <tl_skel.h>
     72
     73#include "tcp.h"
     74#include "tcp_header.h"
    7675
    7776/** TCP module name. */
    78 #define NAME    "TCP protocol"
     77#define NAME  "tcp"
    7978
    8079/** The TCP window default value. */
     
    220219/** TCP global data. */
    221220tcp_globals_t tcp_globals;
    222 
    223 /** Initializes the TCP module.
    224  *
    225  * @param[in] client_connection The client connection processing function. The
    226  *                      module skeleton propagates its own one.
    227  * @return              EOK on success.
    228  * @return              ENOMEM if there is not enough memory left.
    229  */
    230 int tcp_initialize(async_client_conn_t client_connection)
    231 {
    232         int rc;
    233 
    234         assert(client_connection);
    235 
    236         fibril_rwlock_initialize(&tcp_globals.lock);
    237         fibril_rwlock_write_lock(&tcp_globals.lock);
    238 
    239         tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
    240             ICMP_CONNECT_TIMEOUT);
    241         tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
    242             SERVICE_TCP, client_connection);
    243         if (tcp_globals.ip_phone < 0) {
    244                 fibril_rwlock_write_unlock(&tcp_globals.lock);
    245                 return tcp_globals.ip_phone;
    246         }
    247        
    248         rc = socket_ports_initialize(&tcp_globals.sockets);
    249         if (rc != EOK)
    250                 goto out;
    251 
    252         rc = packet_dimensions_initialize(&tcp_globals.dimensions);
    253         if (rc != EOK) {
    254                 socket_ports_destroy(&tcp_globals.sockets);
    255                 goto out;
    256         }
    257 
    258         tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
    259 
    260 out:
    261         fibril_rwlock_write_unlock(&tcp_globals.lock);
    262         return rc;
    263 }
    264221
    265222int tcp_received_msg(device_id_t device_id, packet_t *packet,
     
    12601217 * @see IS_NET_TCP_MESSAGE()
    12611218 */
    1262 int
    1263 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     1219int tl_module_message(ipc_callid_t callid, ipc_call_t *call,
    12641220    ipc_call_t *answer, size_t *answer_count)
    12651221{
    1266         packet_t *packet;
    1267         int rc;
    1268 
    12691222        assert(call);
    12701223        assert(answer);
     
    12731226        *answer_count = 0;
    12741227        switch (IPC_GET_IMETHOD(*call)) {
    1275         case NET_TL_RECEIVED:
    1276 //              fibril_rwlock_read_lock(&tcp_globals.lock);
    1277                 rc = packet_translate_remote(tcp_globals.net_phone, &packet,
    1278                     IPC_GET_PACKET(*call));
    1279                 if (rc != EOK) {
    1280 //                      fibril_rwlock_read_unlock(&tcp_globals.lock);
    1281                         return rc;
    1282                 }
    1283                 rc = tcp_received_msg(IPC_GET_DEVICE(*call), packet, SERVICE_TCP,
    1284                     IPC_GET_ERROR(*call));
    1285 //              fibril_rwlock_read_unlock(&tcp_globals.lock);
    1286                 return rc;
    12871228        case IPC_M_CONNECT_TO_ME:
    12881229                return tcp_process_client_messages(callid, *call);
     
    24862427}
    24872428
    2488 /** Default thread for new connections.
     2429/** Process IPC messages from the IP module
    24892430 *
    2490  * @param[in] iid       The initial message identifier.
    2491  * @param[in] icall     The initial message call structure.
     2431 * @param[in]     iid   Message identifier.
     2432 * @param[in,out] icall Message parameters.
    24922433 *
    24932434 */
    2494 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
    2495 {
    2496         /*
    2497          * Accept the connection
    2498          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    2499          */
    2500         ipc_answer_0(iid, EOK);
    2501 
     2435static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     2436{
     2437        packet_t *packet;
     2438        int rc;
     2439       
    25022440        while (true) {
    2503                 ipc_call_t answer;
    2504                 size_t answer_count;
    2505 
    2506                 /* Clear the answer structure */
    2507                 refresh_answer(&answer, &answer_count);
    2508 
    2509                 /* Fetch the next message */
    2510                 ipc_call_t call;
    2511                 ipc_callid_t callid = async_get_call(&call);
    2512 
    2513                 /* Process the message */
    2514                 int res = tl_module_message_standalone(callid, &call, &answer,
    2515                     &answer_count);
    2516 
    2517                 /*
    2518                  * End if told to either by the message or the processing
    2519                  * result.
    2520                  */
    2521                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    2522                     (res == EHANGUP))
    2523                         return;
    2524 
    2525                 /*
    2526                  * Answer the message
    2527                  */
    2528                 answer_call(callid, res, &answer, answer_count);
    2529         }
    2530 }
    2531 
    2532 /** Starts the module.
     2441                switch (IPC_GET_IMETHOD(*icall)) {
     2442                case NET_TL_RECEIVED:
     2443                        rc = packet_translate_remote(tcp_globals.net_phone, &packet,
     2444                            IPC_GET_PACKET(*icall));
     2445                        if (rc == EOK)
     2446                                rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet,
     2447                                    SERVICE_TCP, IPC_GET_ERROR(*icall));
     2448                       
     2449                        ipc_answer_0(iid, (sysarg_t) rc);
     2450                        break;
     2451                default:
     2452                        ipc_answer_0(iid, (sysarg_t) ENOTSUP);
     2453                }
     2454               
     2455                iid = async_get_call(icall);
     2456        }
     2457}
     2458
     2459/** Initialize the TCP module.
    25332460 *
    2534  * @return              EOK on success.
    2535  * @return              Other error codes as defined for each specific module
    2536  *                      start function.
     2461 * @param[in] net_phone Network module phone.
     2462 *
     2463 * @return EOK on success.
     2464 * @return ENOMEM if there is not enough memory left.
     2465 *
    25372466 */
    2538 int
    2539 main(int argc, char *argv[])
    2540 {
    2541         int rc;
    2542 
    2543         rc = tl_module_start_standalone(tl_client_connection);
     2467int tl_initialize(int net_phone)
     2468{
     2469        fibril_rwlock_initialize(&tcp_globals.lock);
     2470        fibril_rwlock_write_lock(&tcp_globals.lock);
     2471       
     2472        tcp_globals.net_phone = net_phone;
     2473       
     2474        tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
     2475            ICMP_CONNECT_TIMEOUT);
     2476        tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
     2477            SERVICE_TCP, tcp_receiver);
     2478        if (tcp_globals.ip_phone < 0) {
     2479                fibril_rwlock_write_unlock(&tcp_globals.lock);
     2480                return tcp_globals.ip_phone;
     2481        }
     2482       
     2483        int rc = socket_ports_initialize(&tcp_globals.sockets);
     2484        if (rc != EOK)
     2485                goto out;
     2486
     2487        rc = packet_dimensions_initialize(&tcp_globals.dimensions);
     2488        if (rc != EOK) {
     2489                socket_ports_destroy(&tcp_globals.sockets);
     2490                goto out;
     2491        }
     2492
     2493        tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
     2494
     2495out:
     2496        fibril_rwlock_write_unlock(&tcp_globals.lock);
    25442497        return rc;
     2498}
     2499
     2500int main(int argc, char *argv[])
     2501{
     2502        return tl_module_start(SERVICE_TCP);
    25452503}
    25462504
  • uspace/srv/net/tl/udp/Makefile

    r5ccb15c r60b2b69  
    3434
    3535SOURCES = \
    36         udp.c \
    37         udp_module.c
     36        udp.c
    3837
    3938include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/tl/udp/udp.c

    r5ccb15c r60b2b69  
    3535 * @see udp.h
    3636 */
    37 
    38 #include "udp.h"
    39 #include "udp_header.h"
    40 #include "udp_module.h"
    4137
    4238#include <async.h>
     
    6965#include <socket_core.h>
    7066#include <tl_common.h>
    71 #include <tl_local.h>
    72 #include <tl_interface.h>
     67#include <tl_remote.h>
     68#include <tl_skel.h>
     69
     70#include "udp.h"
     71#include "udp_header.h"
    7372
    7473/** UDP module name. */
    75 #define NAME    "UDP protocol"
     74#define NAME  "udp"
    7675
    7776/** Default UDP checksum computing. */
     
    9291/** UDP global data.  */
    9392udp_globals_t udp_globals;
    94 
    95 /** Initializes the UDP module.
    96  *
    97  * @param[in] client_connection The client connection processing function. The
    98  *                      module skeleton propagates its own one.
    99  * @return              EOK on success.
    100  * @return              ENOMEM if there is not enough memory left.
    101  */
    102 int udp_initialize(async_client_conn_t client_connection)
    103 {
    104         measured_string_t names[] = {
    105                 {
    106                         (uint8_t *) "UDP_CHECKSUM_COMPUTING",
    107                         22
    108                 },
    109                 {
    110                         (uint8_t *) "UDP_AUTOBINDING",
    111                         15
    112                 }
    113         };
    114         measured_string_t *configuration;
    115         size_t count = sizeof(names) / sizeof(measured_string_t);
    116         uint8_t *data;
    117         int rc;
    118 
    119         fibril_rwlock_initialize(&udp_globals.lock);
    120         fibril_rwlock_write_lock(&udp_globals.lock);
    121 
    122         udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
    123             ICMP_CONNECT_TIMEOUT);
    124        
    125         udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
    126             SERVICE_UDP, client_connection);
    127         if (udp_globals.ip_phone < 0) {
    128                 fibril_rwlock_write_unlock(&udp_globals.lock);
    129                 return udp_globals.ip_phone;
    130         }
    131 
    132         /* Read default packet dimensions */
    133         rc = ip_packet_size_req(udp_globals.ip_phone, -1,
    134             &udp_globals.packet_dimension);
    135         if (rc != EOK) {
    136                 fibril_rwlock_write_unlock(&udp_globals.lock);
    137                 return rc;
    138         }
    139        
    140         rc = socket_ports_initialize(&udp_globals.sockets);
    141         if (rc != EOK) {
    142                 fibril_rwlock_write_unlock(&udp_globals.lock);
    143                 return rc;
    144         }
    145        
    146         rc = packet_dimensions_initialize(&udp_globals.dimensions);
    147         if (rc != EOK) {
    148                 socket_ports_destroy(&udp_globals.sockets);
    149                 fibril_rwlock_write_unlock(&udp_globals.lock);
    150                 return rc;
    151         }
    152        
    153         udp_globals.packet_dimension.prefix += sizeof(udp_header_t);
    154         udp_globals.packet_dimension.content -= sizeof(udp_header_t);
    155         udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
    156 
    157         udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    158         udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
    159 
    160         /* Get configuration */
    161         configuration = &names[0];
    162         rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
    163             &data);
    164         if (rc != EOK) {
    165                 socket_ports_destroy(&udp_globals.sockets);
    166                 fibril_rwlock_write_unlock(&udp_globals.lock);
    167                 return rc;
    168         }
    169        
    170         if (configuration) {
    171                 if (configuration[0].value)
    172                         udp_globals.checksum_computing =
    173                             (configuration[0].value[0] == 'y');
    174                
    175                 if (configuration[1].value)
    176                         udp_globals.autobinding =
    177                             (configuration[1].value[0] == 'y');
    178 
    179                 net_free_settings(configuration, data);
    180         }
    181 
    182         fibril_rwlock_write_unlock(&udp_globals.lock);
    183         return EOK;
    184 }
    18593
    18694/** Releases the packet and returns the result.
     
    426334}
    427335
     336/** Process IPC messages from the IP module
     337 *
     338 * @param[in]     iid   Message identifier.
     339 * @param[in,out] icall Message parameters.
     340 *
     341 */
     342static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     343{
     344        packet_t *packet;
     345        int rc;
     346       
     347        while (true) {
     348                switch (IPC_GET_IMETHOD(*icall)) {
     349                case NET_TL_RECEIVED:
     350                        rc = packet_translate_remote(udp_globals.net_phone, &packet,
     351                            IPC_GET_PACKET(*icall));
     352                        if (rc == EOK)
     353                                rc = udp_received_msg(IPC_GET_DEVICE(*icall), packet,
     354                                    SERVICE_UDP, IPC_GET_ERROR(*icall));
     355                       
     356                        ipc_answer_0(iid, (sysarg_t) rc);
     357                        break;
     358                default:
     359                        ipc_answer_0(iid, (sysarg_t) ENOTSUP);
     360                }
     361               
     362                iid = async_get_call(icall);
     363        }
     364}
     365
     366/** Initialize the UDP module.
     367 *
     368 * @param[in] net_phone Network module phone.
     369 *
     370 * @return EOK on success.
     371 * @return ENOMEM if there is not enough memory left.
     372 *
     373 */
     374int tl_initialize(int net_phone)
     375{
     376        measured_string_t names[] = {
     377                {
     378                        (uint8_t *) "UDP_CHECKSUM_COMPUTING",
     379                        22
     380                },
     381                {
     382                        (uint8_t *) "UDP_AUTOBINDING",
     383                        15
     384                }
     385        };
     386        measured_string_t *configuration;
     387        size_t count = sizeof(names) / sizeof(measured_string_t);
     388        uint8_t *data;
     389       
     390        fibril_rwlock_initialize(&udp_globals.lock);
     391        fibril_rwlock_write_lock(&udp_globals.lock);
     392       
     393        udp_globals.net_phone = net_phone;
     394       
     395        udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
     396            ICMP_CONNECT_TIMEOUT);
     397       
     398        udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
     399            SERVICE_UDP, udp_receiver);
     400        if (udp_globals.ip_phone < 0) {
     401                fibril_rwlock_write_unlock(&udp_globals.lock);
     402                return udp_globals.ip_phone;
     403        }
     404       
     405        /* Read default packet dimensions */
     406        int rc = ip_packet_size_req(udp_globals.ip_phone, -1,
     407            &udp_globals.packet_dimension);
     408        if (rc != EOK) {
     409                fibril_rwlock_write_unlock(&udp_globals.lock);
     410                return rc;
     411        }
     412       
     413        rc = socket_ports_initialize(&udp_globals.sockets);
     414        if (rc != EOK) {
     415                fibril_rwlock_write_unlock(&udp_globals.lock);
     416                return rc;
     417        }
     418       
     419        rc = packet_dimensions_initialize(&udp_globals.dimensions);
     420        if (rc != EOK) {
     421                socket_ports_destroy(&udp_globals.sockets);
     422                fibril_rwlock_write_unlock(&udp_globals.lock);
     423                return rc;
     424        }
     425       
     426        udp_globals.packet_dimension.prefix += sizeof(udp_header_t);
     427        udp_globals.packet_dimension.content -= sizeof(udp_header_t);
     428        udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
     429
     430        udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
     431        udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
     432
     433        /* Get configuration */
     434        configuration = &names[0];
     435        rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
     436            &data);
     437        if (rc != EOK) {
     438                socket_ports_destroy(&udp_globals.sockets);
     439                fibril_rwlock_write_unlock(&udp_globals.lock);
     440                return rc;
     441        }
     442       
     443        if (configuration) {
     444                if (configuration[0].value)
     445                        udp_globals.checksum_computing =
     446                            (configuration[0].value[0] == 'y');
     447               
     448                if (configuration[1].value)
     449                        udp_globals.autobinding =
     450                            (configuration[1].value[0] == 'y');
     451
     452                net_free_settings(configuration, data);
     453        }
     454
     455        fibril_rwlock_write_unlock(&udp_globals.lock);
     456        return EOK;
     457}
     458
    428459/** Sends data from the socket to the remote address.
    429460 *
     
    860891 * @see IS_NET_UDP_MESSAGE()
    861892 */
    862 int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     893int tl_module_message(ipc_callid_t callid, ipc_call_t *call,
    863894    ipc_call_t *answer, size_t *answer_count)
    864895{
    865         packet_t *packet;
    866         int rc;
    867 
    868896        *answer_count = 0;
    869897
    870898        switch (IPC_GET_IMETHOD(*call)) {
    871         case NET_TL_RECEIVED:
    872                 rc = packet_translate_remote(udp_globals.net_phone, &packet,
    873                     IPC_GET_PACKET(*call));
    874                 if (rc != EOK)
    875                         return rc;
    876                 return udp_received_msg(IPC_GET_DEVICE(*call), packet,
    877                     SERVICE_UDP, IPC_GET_ERROR(*call));
    878899        case IPC_M_CONNECT_TO_ME:
    879900                return udp_process_client_messages(callid, *call);
     
    883904}
    884905
    885 /** Default thread for new connections.
    886  *
    887  * @param[in] iid       The initial message identifier.
    888  * @param[in] icall     The initial message call structure.
    889  */
    890 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
    891 {
    892         /*
    893          * Accept the connection
    894          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    895          */
    896         ipc_answer_0(iid, EOK);
    897        
    898         while (true) {
    899                 ipc_call_t answer;
    900                 size_t answer_count;
    901                
    902                 /* Clear the answer structure */
    903                 refresh_answer(&answer, &answer_count);
    904                
    905                 /* Fetch the next message */
    906                 ipc_call_t call;
    907                 ipc_callid_t callid = async_get_call(&call);
    908                
    909                 /* Process the message */
    910                 int res = tl_module_message_standalone(callid, &call, &answer,
    911                     &answer_count);
    912                
    913                 /*
    914                  * End if told to either by the message or the processing
    915                  * result.
    916                  */
    917                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    918                     (res == EHANGUP))
    919                         return;
    920                
    921                 /* Answer the message */
    922                 answer_call(callid, res, &answer, answer_count);
    923         }
    924 }
    925 
    926 /** Starts the module.
    927  *
    928  * @return              EOK on success.
    929  * @return              Other error codes as defined for each specific module
    930  *                      start function.
    931  */
    932906int main(int argc, char *argv[])
    933907{
    934         int rc;
    935        
    936908        /* Start the module */
    937         rc = tl_module_start_standalone(tl_client_connection);
    938         return rc;
     909        return tl_module_start(SERVICE_UDP);
    939910}
    940911
Note: See TracChangeset for help on using the changeset viewer.