Changes in / [8426912a:6610565b] in mainline


Ignore:
Files:
27 added
14 deleted
51 edited

Legend:

Unmodified
Added
Removed
  • boot/Makefile.common

    r8426912a r6610565b  
    9898        $(USPACE_PATH)/srv/fs/fat/fat \
    9999        $(USPACE_PATH)/srv/taskmon/taskmon \
    100         $(USPACE_PATH)/srv/hw/netif/ne2000/ne2000 \
     100        $(USPACE_PATH)/srv/hw/netif/dp8390/dp8390 \
     101        $(USPACE_PATH)/srv/hw/bus/usb/hcd/virtual/vhcd \
    101102        $(USPACE_PATH)/srv/net/netif/lo/lo \
    102103        $(USPACE_PATH)/srv/net/nil/eth/eth \
     
    132133        $(USPACE_PATH)/app/taskdump/taskdump \
    133134        $(USPACE_PATH)/app/tester/tester \
     135        $(USPACE_PATH)/app/test_serial/test_serial \
    134136        $(USPACE_PATH)/app/tetris/tetris \
    135137        $(USPACE_PATH)/app/trace/trace \
     138        $(USPACE_PATH)/app/netstart/netstart \
    136139        $(USPACE_PATH)/app/nettest1/nettest1 \
    137140        $(USPACE_PATH)/app/nettest2/nettest2 \
  • kernel/arch/amd64/include/interrupt.h

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

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

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

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

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

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

    r8426912a r6610565b  
    5454extern sysarg_t sys_physmem_map(sysarg_t, sysarg_t, sysarg_t, sysarg_t);
    5555extern sysarg_t sys_iospace_enable(ddi_ioarg_t *);
     56extern sysarg_t sys_interrupt_enable(int irq, int enable);
    5657
    5758/*
  • kernel/generic/include/syscall/syscall.h

    r8426912a r6610565b  
    8282        SYS_PHYSMEM_MAP,
    8383        SYS_IOSPACE_ENABLE,
     84        SYS_INTERRUPT_ENABLE,
    8485       
    8586        SYS_SYSINFO_GET_TAG,
  • kernel/generic/src/ddi/ddi.c

    r8426912a r6610565b  
    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 */
     267sysarg_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
    260290/** @}
    261291 */
  • kernel/generic/src/mm/slab.c

    r8426912a r6610565b  
    806806}
    807807
    808 /** Go through all caches and reclaim what is possible */
     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 */
    809814size_t slab_reclaim(unsigned int flags)
    810815{
    811         irq_spinlock_lock(&slab_cache_lock, true);
     816        irq_spinlock_lock(&slab_cache_lock, false);
    812817       
    813818        size_t frames = 0;
     
    819824        }
    820825       
    821         irq_spinlock_unlock(&slab_cache_lock, true);
     826        irq_spinlock_unlock(&slab_cache_lock, false);
    822827       
    823828        return frames;
  • kernel/generic/src/syscall/syscall.c

    r8426912a r6610565b  
    171171        (syshandler_t) sys_physmem_map,
    172172        (syshandler_t) sys_iospace_enable,
     173        (syshandler_t) sys_interrupt_enable,
    173174       
    174175        /* Sysinfo syscalls */
  • uspace/Makefile

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

    r8426912a r6610565b  
    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 },
    7576
    7677    [SYS_SYSINFO_GET_TAG] = { "sysinfo_get_tag",                2,      V_INTEGER },
  • uspace/doc/doxygroups.h

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

    r8426912a r6610565b  
    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;
    433439       
    434440        /* Enable interrupt on the serial port. */
  • uspace/lib/c/generic/ddi.c

    r8426912a r6610565b  
    9696}
    9797
     98/** Enable an interrupt.
     99 *
     100 * @param irq the interrupt.
     101 *
     102 * @return Zero on success, negative error code otherwise.
     103 */
     104int 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 */
     115int interrupt_disable(int irq)
     116{
     117        return __SYSCALL2(SYS_INTERRUPT_ENABLE, (sysarg_t) irq, 0);
     118}
     119
    98120/** Enable PIO for specified I/O range.
    99121 *
  • uspace/lib/c/generic/devman.c

    r8426912a r6610565b  
    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                 }
    8887               
    8988                fibril_mutex_unlock(&devman_phone_mutex);
  • uspace/lib/c/include/ddi.h

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

    r8426912a r6610565b  
    3333/** @file
    3434 * Internetwork layer modules messages.
    35  * @see il_remote.h
     35 * @see il_interface.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,
    4751        /** Device state changed message.
    4852         * @see il_device_state_msg()
    4953         */
    50         NET_IL_DEVICE_STATE = NET_IL_FIRST,
    51        
     54        NET_IL_DEVICE_STATE,
    5255        /** Device MTU changed message.
    5356         * @see il_mtu_changed_msg()
    5457         */
    5558        NET_IL_MTU_CHANGED,
    56        
     59        /** Packet size message.
     60         * @see il_packet_size_req()
     61         */
     62        NET_IL_PACKET_SPACE,
    5763        /** Packet received message.
    5864         * @see il_received_msg()
    5965         */
    60         NET_IL_RECEIVED
     66        NET_IL_RECEIVED,
     67        /** Packet send message.
     68         * @see il_send_msg()
     69         */
     70        NET_IL_SEND
    6171} il_messages;
    6272
  • uspace/lib/c/include/ipc/ip.h

    r8426912a r6610565b  
    4747/** IP module messages. */
    4848typedef enum {
    49         /** New device message.
    50          * @see ip_device_req()
    51          */
    52         NET_IP_DEVICE = NET_IP_FIRST,
    53        
    5449        /** Adds the routing entry.
    5550         * @see ip_add_route()
    5651         */
    57         NET_IP_ADD_ROUTE,
     52        NET_IP_ADD_ROUTE = NET_IP_FIRST,
    5853       
    5954        /** Gets the actual route information.
     
    7065         * @see ip_set_default_gateway()
    7166         */
    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
     67        NET_IP_SET_GATEWAY
    8368} ip_messages;
    8469
  • uspace/lib/c/include/ipc/services.h

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

    r8426912a r6610565b  
    4343        netif/netif_skel.c \
    4444        nil/nil_remote.c \
    45         nil/nil_skel.c \
    46         il/il_remote.c \
    47         il/il_skel.c \
     45        il/il_interface.c \
    4846        il/ip_remote.c \
    4947        il/ip_client.c \
     
    5250        tl/icmp_client.c \
    5351        tl/socket_core.c \
    54         tl/tl_common.c \
    55         tl/tl_remote.c \
    56         tl/tl_skel.c
     52        tl/tl_interface.c \
     53        tl/tl_common.c
    5754
    5855include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/net/generic/protocol_map.c

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

    r8426912a r6610565b  
    3636 *
    3737 * @see ip_interface.h
    38  * @see il_remote.h
     38 * @see il_interface.h
    3939 *
    4040 */
     
    121121    services_t service)
    122122{
    123         return generic_device_req_remote(ip_phone, NET_IP_DEVICE, device_id, 0,
     123        return generic_device_req_remote(ip_phone, NET_IL_DEVICE, device_id, 0,
    124124            service);
    125125}
     
    188188    packet_dimension_t *packet_dimension)
    189189{
    190         return generic_packet_size_req_remote(ip_phone, NET_IP_PACKET_SPACE,
     190        return generic_packet_size_req_remote(ip_phone, NET_IL_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_IP_SEND, device_id,
     230        return generic_send_msg_remote(ip_phone, NET_IL_SEND, device_id,
    231231            packet_get_id(packet), sender, error);
    232232}
  • uspace/lib/net/include/nil_remote.h

    r8426912a r6610565b  
    3737#include <net/device.h>
    3838#include <net/packet.h>
    39 #include <generic.h>
    4039
    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 
    63 extern int nil_device_state_msg(int, device_id_t, int);
    64 extern int nil_received_msg(int, device_id_t, packet_t *, services_t);
     40extern int nil_device_state_msg_remote(int, device_id_t, int);
     41extern int nil_received_msg_remote(int, device_id_t, packet_t *, services_t);
    6542
    6643#endif
  • uspace/lib/net/netif/netif_skel.c

    r8426912a r6610565b  
    3333/** @file
    3434 * Network interface module skeleton implementation.
    35  * @see netif_skel.h
     35 * @see netif.h
    3636 */
    3737
     
    5252#include <adt/measured_strings.h>
    5353#include <net/device.h>
     54#include <nil_interface.h>
    5455#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                fibril_rwlock_write_unlock(&netif_globals.lock);
    132133                nil_device_state_msg(phone, device_id, result);
    133                 fibril_rwlock_write_unlock(&netif_globals.lock);
    134134                return EOK;
    135135        }
     
    166166        if (result > NETIF_NULL) {
    167167                int phone = device->nil_phone;
     168                fibril_rwlock_write_unlock(&netif_globals.lock);
    168169                nil_device_state_msg(phone, device_id, result);
    169                 fibril_rwlock_write_unlock(&netif_globals.lock);
    170170                return EOK;
    171171        }
  • uspace/lib/net/nil/nil_remote.c

    r8426912a r6610565b  
    3333/** @file
    3434 * Network interface layer interface implementation for remote modules.
    35  * @see nil_remote.h
     35 * @see nil_interface.h
    3636 */
    3737
    3838#include <nil_remote.h>
     39#include <nil_interface.h>
    3940#include <generic.h>
    4041#include <net/device.h>
    4142#include <net/packet.h>
    4243#include <packet_client.h>
     44
    4345#include <ipc/nil.h>
    4446
    4547/** Notify the network interface layer about the device state change.
    4648 *
    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  *
     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.
    5555 */
    56 int nil_device_state_msg(int nil_phone, device_id_t device_id, int state)
     56int nil_device_state_msg_remote(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 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  *
     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.
    7674 */
    77 int nil_received_msg(int nil_phone, device_id_t device_id,
     75int nil_received_msg_remote(int nil_phone, device_id_t device_id,
    7876    packet_t *packet, services_t target)
    7977{
  • uspace/lib/net/tl/tl_common.c

    r8426912a r6610565b  
    4242#include <ip_remote.h>
    4343#include <ip_interface.h>
    44 #include <tl_remote.h>
     44#include <tl_interface.h>
    4545
    4646#include <net/socket_codes.h>
  • uspace/srv/net/cfg/ne2k

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

    r8426912a r6610565b  
    3434
    3535SOURCES = \
    36         arp.c
     36        arp.c \
     37        arp_module.c
    3738
    3839include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/il/arp/arp.c

    r8426912a r6610565b  
    3636 */
    3737
     38#include "arp.h"
     39#include "arp_header.h"
     40#include "arp_oc.h"
     41#include "arp_module.h"
     42
    3843#include <async.h>
    3944#include <malloc.h>
    4045#include <mem.h>
    4146#include <fibril_synch.h>
    42 #include <assert.h>
    4347#include <stdio.h>
    4448#include <str.h>
     
    5054#include <ipc/arp.h>
    5155#include <ipc/il.h>
    52 #include <ipc/nil.h>
    5356#include <byteorder.h>
    5457#include <errno.h>
     58
    5559#include <net/modules.h>
    5660#include <net/device.h>
    5761#include <net/packet.h>
    58 #include <nil_remote.h>
     62
     63#include <nil_interface.h>
    5964#include <protocol_map.h>
    6065#include <packet_client.h>
    6166#include <packet_remote.h>
    62 #include <il_remote.h>
    63 #include <il_skel.h>
    64 #include "arp.h"
     67#include <il_interface.h>
     68#include <il_local.h>
     69
    6570
    6671/** ARP module name. */
     
    6873
    6974/** Number of microseconds to wait for an ARP reply. */
    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  */
    86 typedef struct arp_header arp_header_t;
    87 
    88 /** ARP protocol header. */
    89 struct 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));
     75#define ARP_TRANS_WAIT  1000000
    10976
    11077/** ARP global data. */
     
    12188                trans->hw_addr = NULL;
    12289        }
    123        
    12490        fibril_condvar_broadcast(&trans->cv);
    12591}
     
    12894{
    12995        int count;
    130        
     96        arp_trans_t *trans;
     97
    13198        for (count = arp_addr_count(addresses) - 1; count >= 0; count--) {
    132                 arp_trans_t *trans = arp_addr_items_get_index(&addresses->values,
    133                     count);
     99                trans = arp_addr_items_get_index(&addresses->values, count);
    134100                if (trans)
    135101                        arp_clear_trans(trans);
     
    137103}
    138104
    139 /** Clear the device specific data.
    140  *
    141  * @param[in] device Device specific data.
     105
     106/** Clears the device specific data.
     107 *
     108 * @param[in] device    The device specific data.
    142109 */
    143110static void arp_clear_device(arp_device_t *device)
    144111{
    145112        int count;
    146        
     113        arp_proto_t *proto;
     114
    147115        for (count = arp_protos_count(&device->protos) - 1; count >= 0;
    148116            count--) {
    149                 arp_proto_t *proto = arp_protos_get_index(&device->protos,
    150                     count);
    151                
     117                proto = arp_protos_get_index(&device->protos, count);
    152118                if (proto) {
    153119                        if (proto->addr)
    154120                                free(proto->addr);
    155                        
    156121                        if (proto->addr_data)
    157122                                free(proto->addr_data);
    158                        
    159123                        arp_clear_addr(&proto->addresses);
    160124                        arp_addr_destroy(&proto->addresses);
    161125                }
    162126        }
    163        
    164127        arp_protos_clear(&device->protos);
    165128}
     
    168131{
    169132        int count;
    170        
     133        arp_device_t *device;
     134
    171135        fibril_mutex_lock(&arp_globals.lock);
    172136        for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0;
    173137            count--) {
    174                 arp_device_t *device = arp_cache_get_index(&arp_globals.cache,
    175                     count);
    176                
     138                device = arp_cache_get_index(&arp_globals.cache, count);
    177139                if (device) {
    178140                        arp_clear_device(device);
    179141                        if (device->addr_data)
    180142                                free(device->addr_data);
    181                        
    182143                        if (device->broadcast_data)
    183144                                free(device->broadcast_data);
    184145                }
    185146        }
    186        
    187147        arp_cache_clear(&arp_globals.cache);
    188148        fibril_mutex_unlock(&arp_globals.lock);
    189        
     149        printf("Cache cleaned\n");
    190150        return EOK;
    191151}
     
    194154    services_t protocol, measured_string_t *address)
    195155{
     156        arp_device_t *device;
     157        arp_proto_t *proto;
     158        arp_trans_t *trans;
     159
    196160        fibril_mutex_lock(&arp_globals.lock);
    197        
    198         arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     161        device = arp_cache_find(&arp_globals.cache, device_id);
    199162        if (!device) {
    200163                fibril_mutex_unlock(&arp_globals.lock);
    201164                return ENOENT;
    202165        }
    203        
    204         arp_proto_t *proto = arp_protos_find(&device->protos, protocol);
     166        proto = arp_protos_find(&device->protos, protocol);
    205167        if (!proto) {
    206168                fibril_mutex_unlock(&arp_globals.lock);
    207169                return ENOENT;
    208170        }
    209        
    210         arp_trans_t *trans = arp_addr_find(&proto->addresses, address->value,
    211             address->length);
     171        trans = arp_addr_find(&proto->addresses, address->value, address->length);
    212172        if (trans)
    213173                arp_clear_trans(trans);
    214        
    215174        arp_addr_exclude(&proto->addresses, address->value, address->length);
    216        
    217175        fibril_mutex_unlock(&arp_globals.lock);
    218176        return EOK;
    219177}
    220178
     179
    221180static int arp_clear_device_req(int arp_phone, device_id_t device_id)
    222181{
     182        arp_device_t *device;
     183
    223184        fibril_mutex_lock(&arp_globals.lock);
    224        
    225         arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     185        device = arp_cache_find(&arp_globals.cache, device_id);
    226186        if (!device) {
    227187                fibril_mutex_unlock(&arp_globals.lock);
    228188                return ENOENT;
    229189        }
    230        
    231190        arp_clear_device(device);
    232        
     191        printf("Device %d cleared\n", device_id);
    233192        fibril_mutex_unlock(&arp_globals.lock);
    234193        return EOK;
    235194}
    236195
    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  *
     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.
    248205 */
    249206static int arp_proto_create(arp_proto_t **proto, services_t service,
    250207    measured_string_t *address)
    251208{
     209        int rc;
     210
    252211        *proto = (arp_proto_t *) malloc(sizeof(arp_proto_t));
    253212        if (!*proto)
     
    258217        (*proto)->addr_data = address->value;
    259218       
    260         int rc = arp_addr_initialize(&(*proto)->addresses);
     219        rc = arp_addr_initialize(&(*proto)->addresses);
    261220        if (rc != EOK) {
    262221                free(*proto);
     
    267226}
    268227
    269 /** Process the received ARP packet.
    270  *
    271  * Update the source hardware address if the source entry exists or the packet
     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 */
     244static 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;
     251        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 */
     391int 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 */
     411static 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
    272430 * is targeted to my protocol address.
    273  *
    274  * Respond to the ARP request if the packet is the ARP request and is
     431 * Responses to the ARP request if the packet is the ARP request and is
    275432 * targeted to my address.
    276433 *
    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  *
     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.
    291446 */
    292447static int arp_receive_message(device_id_t device_id, packet_t *packet)
    293448{
     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;
    294458        int rc;
    295459       
    296         size_t length = packet_get_data_length(packet);
     460        length = packet_get_data_length(packet);
    297461        if (length <= sizeof(arp_header_t))
    298462                return EINVAL;
    299        
    300         arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     463
     464        device = arp_cache_find(&arp_globals.cache, device_id);
    301465        if (!device)
    302466                return ENOENT;
    303        
    304         arp_header_t *header = (arp_header_t *) packet_get_data(packet);
     467
     468        header = (arp_header_t *) packet_get_data(packet);
    305469        if ((ntohs(header->hardware) != device->hardware) ||
    306470            (length < sizeof(arp_header_t) + header->hardware_length * 2U +
     
    308472                return EINVAL;
    309473        }
    310        
    311         arp_proto_t *proto = arp_protos_find(&device->protos,
     474
     475        proto = arp_protos_find(&device->protos,
    312476            protocol_unmap(device->service, ntohs(header->protocol)));
    313477        if (!proto)
    314478                return ENOENT;
    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,
     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,
    322485            header->protocol_length);
    323        
    324         if ((trans) && (trans->hw_addr)) {
    325                 /* Translation exists */
     486        /* Exists? */
     487        if (trans && trans->hw_addr) {
    326488                if (trans->hw_addr->length != header->hardware_length)
    327489                        return EINVAL;
    328                
    329490                memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
    330491        }
    331        
    332492        /* Is my protocol address? */
    333493        if (proto->addr->length != header->protocol_length)
     
    335495       
    336496        if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
     497                /* Not already updated? */
    337498                if (!trans) {
    338                         /* Update the translation */
    339499                        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
    340500                        if (!trans)
    341501                                return ENOMEM;
    342                        
    343502                        trans->hw_addr = NULL;
    344503                        fibril_condvar_initialize(&trans->cv);
     
    350509                        }
    351510                }
    352                
    353511                if (!trans->hw_addr) {
    354512                        trans->hw_addr = measured_string_create_bulk(src_hw,
     
    360518                        fibril_condvar_broadcast(&trans->cv);
    361519                }
    362                
    363520                if (ntohs(header->operation) == ARPOP_REQUEST) {
    364521                        header->operation = htons(ARPOP_REPLY);
     
    381538                }
    382539        }
    383        
     540
    384541        return EOK;
    385542}
    386543
    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  */
    396 static 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);
     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 */
     558static int
     559arp_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;
     566        packet_t *packet;
     567        arp_header_t *header;
     568        bool retry = false;
     569        int rc;
     570
     571restart:
     572        if (!target || !translation)
     573                return EBADMEM;
     574
     575        device = arp_cache_find(&arp_globals.cache, device_id);
     576        if (!device)
    403577                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  */
    421 static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall)
    422 {
    423         packet_t *packet;
    424         int rc;
    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  */
    485 static 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)
     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)
    530594                        return ENOENT;
    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 
    630 int 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 
    642 static 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 {
     595                retry = true;
     596                goto restart;
     597        }
     598        if (retry)
     599                return EAGAIN;
     600
    645601        /* ARP packet content size = header + (address + translation) * 2 */
    646         size_t length = 8 + 2 * (proto->addr->length + device->addr->length);
     602        length = 8 + 2 * (proto->addr->length + device->addr->length);
    647603        if (length > device->packet_dimension.content)
    648604                return ELIMIT;
    649        
    650         packet_t *packet = packet_get_4_remote(arp_globals.net_phone,
     605
     606        packet = packet_get_4_remote(arp_globals.net_phone,
    651607            device->packet_dimension.addr_len, device->packet_dimension.prefix,
    652608            length, device->packet_dimension.suffix);
    653609        if (!packet)
    654610                return ENOMEM;
    655        
    656         arp_header_t *header = (arp_header_t *) packet_suffix(packet, length);
     611
     612        header = (arp_header_t *) packet_suffix(packet, length);
    657613        if (!header) {
    658614                pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
    659615                return ENOMEM;
    660616        }
    661        
     617
    662618        header->hardware = htons(device->hardware);
    663619        header->hardware_length = (uint8_t) device->addr->length;
     
    665621        header->protocol_length = (uint8_t) proto->addr->length;
    666622        header->operation = htons(ARPOP_REQUEST);
    667        
    668623        length = sizeof(arp_header_t);
    669        
    670624        memcpy(((uint8_t *) header) + length, device->addr->value,
    671625            device->addr->length);
     
    677631        length += device->addr->length;
    678632        memcpy(((uint8_t *) header) + length, target->value, target->length);
    679        
    680         int rc = packet_set_addr(packet, (uint8_t *) device->addr->value,
     633
     634        rc = packet_set_addr(packet, (uint8_t *) device->addr->value,
    681635            (uint8_t *) device->broadcast_addr->value, device->addr->length);
    682636        if (rc != EOK) {
     
    684638                return rc;
    685639        }
    686        
     640
    687641        nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
    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  */
    706 static 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        
    714 restart:
    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        
     642
    787643        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
    788644        if (!trans)
    789645                return ENOMEM;
    790        
    791646        trans->hw_addr = NULL;
    792647        fibril_condvar_initialize(&trans->cv);
    793        
    794648        rc = arp_addr_add(&proto->addresses, target->value, target->length,
    795649            trans);
     
    801655        rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock,
    802656            ARP_TRANS_WAIT);
    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);
     657        if (rc == ETIMEOUT)
    811658                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 
    821659        retry = true;
    822660        goto restart;
    823661}
    824662
    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.
     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.
    834673 *
    835674 * @see arp_interface.h
    836675 * @see IS_NET_ARP_MESSAGE()
    837  *
    838  */
    839 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    840     size_t *count)
     676 */
     677int
     678arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     679    ipc_call_t *answer, size_t *answer_count)
    841680{
    842681        measured_string_t *address;
    843682        measured_string_t *translation;
    844683        uint8_t *data;
     684        packet_t *packet;
     685        packet_t *next;
    845686        int rc;
    846687       
    847         *count = 0;
     688        *answer_count = 0;
    848689        switch (IPC_GET_IMETHOD(*call)) {
    849690        case IPC_M_PHONE_HUNGUP:
     
    861702                        free(data);
    862703                }
    863                
    864704                return rc;
    865705       
     
    874714                free(address);
    875715                free(data);
    876                
    877716                if (rc != EOK) {
    878717                        fibril_mutex_unlock(&arp_globals.lock);
    879718                        return rc;
    880719                }
    881                
    882720                if (!translation) {
    883721                        fibril_mutex_unlock(&arp_globals.lock);
    884722                        return ENOENT;
    885723                }
    886                
    887724                rc = measured_strings_reply(translation, 1);
    888725                fibril_mutex_unlock(&arp_globals.lock);
    889726                return rc;
    890        
     727
    891728        case NET_ARP_CLEAR_DEVICE:
    892729                return arp_clear_device_req(0, IPC_GET_DEVICE(*call));
    893        
     730
    894731        case NET_ARP_CLEAR_ADDRESS:
    895732                rc = measured_strings_receive(&address, &data, 1);
     
    905742        case NET_ARP_CLEAN_CACHE:
    906743                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));
    907773        }
    908774       
     
    910776}
    911777
     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 */
     783static 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 */
    912825int main(int argc, char *argv[])
    913826{
     827        int rc;
     828       
    914829        /* Start the module */
    915         return il_module_start(SERVICE_ARP);
     830        rc = il_module_start_standalone(il_client_connection);
     831        return rc;
    916832}
    917833
    918834/** @}
    919835 */
     836
  • uspace/srv/net/il/arp/arp.h

    r8426912a r6610565b  
    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       
    127133        /** Networking module phone. */
    128134        int net_phone;
  • uspace/srv/net/il/ip/Makefile

    r8426912a r6610565b  
    3434
    3535SOURCES = \
    36         ip.c
     36        ip.c \
     37        ip_module.c
    3738
    3839include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/il/ip/ip.c

    r8426912a r6610565b  
    3535 * @see arp.h
    3636 */
     37
     38#include "ip.h"
     39#include "ip_module.h"
    3740
    3841#include <async.h>
     
    4952#include <sys/types.h>
    5053#include <byteorder.h>
    51 #include "ip.h"
    5254
    5355#include <adt/measured_strings.h>
     
    6870#include <icmp_client.h>
    6971#include <icmp_interface.h>
     72#include <il_interface.h>
    7073#include <ip_client.h>
    7174#include <ip_interface.h>
    7275#include <ip_header.h>
    7376#include <net_interface.h>
    74 #include <nil_remote.h>
    75 #include <tl_remote.h>
     77#include <nil_interface.h>
     78#include <tl_interface.h>
    7679#include <packet_remote.h>
    77 #include <il_remote.h>
    78 #include <il_skel.h>
     80#include <il_local.h>
    7981
    8082/** IP module name. */
     
    120122INT_MAP_IMPLEMENT(ip_protos, ip_proto_t);
    121123GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t);
    122 
    123 static void ip_receiver(ipc_callid_t, ipc_call_t *);
    124124
    125125/** Releases the packet and returns the result.
     
    244244}
    245245
    246 int il_initialize(int net_phone)
    247 {
     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 */
     253int ip_initialize(async_client_conn_t client_connection)
     254{
     255        int rc;
     256
    248257        fibril_rwlock_initialize(&ip_globals.lock);
    249258        fibril_rwlock_write_lock(&ip_globals.lock);
    250259        fibril_rwlock_initialize(&ip_globals.protos_lock);
    251260        fibril_rwlock_initialize(&ip_globals.netifs_lock);
    252        
    253         ip_globals.net_phone = net_phone;
    254261        ip_globals.packet_counter = 0;
    255262        ip_globals.gateway.address.s_addr = 0;
     
    257264        ip_globals.gateway.gateway.s_addr = 0;
    258265        ip_globals.gateway.netif = NULL;
    259        
    260         int rc = ip_netifs_initialize(&ip_globals.netifs);
     266        ip_globals.client_connection = client_connection;
     267       
     268        rc = ip_netifs_initialize(&ip_globals.netifs);
    261269        if (rc != EOK)
    262270                goto out;
     
    423431        ip_netif->phone = nil_bind_service(ip_netif->service,
    424432            (sysarg_t) ip_netif->device_id, SERVICE_IP,
    425             ip_receiver);
     433            ip_globals.client_connection);
    426434        if (ip_netif->phone < 0) {
    427435                printf("Failed to contact the nil service %d\n",
     
    479487}
    480488
    481 static 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;
     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 */
     496static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
     497{
     498        ip_netif_t *netif;
    502499
    503500        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    504 
    505         rc = ip_netif_initialize(ip_netif);
    506         if (rc != EOK) {
     501        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     502        if (!netif) {
    507503                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);
     504                return ENOENT;
     505        }
     506        netif->packet_dimension.content = mtu;
    543507        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    544508
    545         printf("%s: Broadcast (%s)\n", NAME, address);
     509        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
    546510
    547511        return EOK;
    548512}
    549513
    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  */
    558 static 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)
     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 */
     521static 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 */
     549static ip_header_t *
     550ip_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)
    565556                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  */
    585 static ip_route_t *ip_find_route(in_addr_t destination) {
    586         int index;
    587         ip_route_t *route;
    588         ip_netif_t *netif;
    589 
    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  */
    611 static 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;
     557        memcpy(middle, last, IP_HEADER_LENGTH(last));
     558        middle->flags |= IPFLAG_MORE_FRAGMENTS;
     559        return middle;
    617560}
    618561
     
    683626 *                      function.
    684627 */
    685 static int ip_prepare_packet(in_addr_t *source, in_addr_t dest,
    686     packet_t *packet, measured_string_t *destination)
     628static int
     629ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet,
     630    measured_string_t *destination)
    687631{
    688632        size_t length;
     
    813757 *                      function.
    814758 */
    815 static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
     759static int
     760ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
    816761    ip_header_t *header, ip_header_t *new_header, size_t length,
    817762    const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen)
     
    847792
    848793        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  */
    859 static 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;
    870794}
    871795
     
    1072996 *                      function.
    1073997 */
    1074 static 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)
     998static int
     999ip_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)
    10761001{
    10771002        measured_string_t destination;
     
    11361061}
    11371062
    1138 static int ip_send_msg_local(int il_phone, device_id_t device_id,
    1139     packet_t *packet, services_t sender, services_t error)
     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 */
     1071static ip_route_t *
     1072ip_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 */
     1098static 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 */
     1124static 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 */
     1148static int
     1149ip_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
     1182static int
     1183ip_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
     1251static int
     1252ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet,
     1253    services_t sender, services_t error)
    11401254{
    11411255        int addrlen;
     
    12411355}
    12421356
    1243 /** Updates the device state.
    1244  *
     1357/** Returns the device packet dimensions for sending.
     1358 *
     1359 * @param[in] phone     The service module phone.
     1360 * @param[in] message   The service specific message.
    12451361 * @param[in] device_id The device identifier.
    1246  * @param[in] state     The new state value.
     1362 * @param[out] addr_len The minimum reserved address length.
     1363 * @param[out] prefix   The minimum reserved prefix size.
     1364 * @param[out] content  The maximum content size.
     1365 * @param[out] suffix   The minimum reserved suffix size.
    12471366 * @return              EOK on success.
    1248  * @return              ENOENT if device is not found.
    1249  */
    1250 static int ip_device_state_message(device_id_t device_id, device_state_t state)
     1367 */
     1368static int
     1369ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix,
     1370    size_t *content, size_t *suffix)
    12511371{
    12521372        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);
     1373        int index;
     1374
     1375        if (!addr_len || !prefix || !content || !suffix)
     1376                return EBADMEM;
     1377
     1378        *content = IP_MAX_CONTENT - IP_PREFIX;
     1379        fibril_rwlock_read_lock(&ip_globals.netifs_lock);
     1380        if (device_id < 0) {
     1381                *addr_len = IP_ADDR;
     1382                *prefix = 0;
     1383                *suffix = 0;
     1384
     1385                for (index = ip_netifs_count(&ip_globals.netifs) - 1;
     1386                    index >= 0; index--) {
     1387                        netif = ip_netifs_get_index(&ip_globals.netifs, index);
     1388                        if (!netif)
     1389                                continue;
     1390                       
     1391                        if (netif->packet_dimension.addr_len > *addr_len)
     1392                                *addr_len = netif->packet_dimension.addr_len;
     1393                       
     1394                        if (netif->packet_dimension.prefix > *prefix)
     1395                                *prefix = netif->packet_dimension.prefix;
     1396                               
     1397                        if (netif->packet_dimension.suffix > *suffix)
     1398                                *suffix = netif->packet_dimension.suffix;
     1399                }
     1400
     1401                *prefix = *prefix + IP_PREFIX;
     1402                *suffix = *suffix + IP_SUFFIX;
     1403        } else {
     1404                netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1405                if (!netif) {
     1406                        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
     1407                        return ENOENT;
     1408                }
     1409
     1410                *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?
     1411                    netif->packet_dimension.addr_len : IP_ADDR;
     1412                *prefix = netif->packet_dimension.prefix + IP_PREFIX;
     1413                *suffix = netif->packet_dimension.suffix + IP_SUFFIX;
     1414        }
     1415        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    12651416
    12661417        return EOK;
     
    13021453 *                      tl_received_msg() function.
    13031454 */
    1304 static int ip_deliver_local(device_id_t device_id, packet_t *packet,
    1305     ip_header_t *header, services_t error)
     1455static int
     1456ip_deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header,
     1457    services_t error)
    13061458{
    13071459        ip_proto_t *proto;
     
    14031555 *                      is disabled.
    14041556 */
    1405 static int ip_process_packet(device_id_t device_id, packet_t *packet)
     1557static int
     1558ip_process_packet(device_id_t device_id, packet_t *packet)
    14061559{
    14071560        ip_header_t *header;
     
    14931646}
    14941647
    1495 /** Returns the device packet dimensions for sending.
    1496  *
    1497  * @param[in] phone     The service module phone.
    1498  * @param[in] message   The service specific message.
    1499  * @param[in] device_id The device identifier.
    1500  * @param[out] addr_len The minimum reserved address length.
    1501  * @param[out] prefix   The minimum reserved prefix size.
    1502  * @param[out] content  The maximum content size.
    1503  * @param[out] suffix   The minimum reserved suffix size.
    1504  * @return              EOK on success.
    1505  */
    1506 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,
    1507     size_t *prefix, size_t *content, size_t *suffix)
    1508 {
    1509         ip_netif_t *netif;
    1510         int index;
    1511 
    1512         if (!addr_len || !prefix || !content || !suffix)
    1513                 return EBADMEM;
    1514 
    1515         *content = IP_MAX_CONTENT - IP_PREFIX;
    1516         fibril_rwlock_read_lock(&ip_globals.netifs_lock);
    1517         if (device_id < 0) {
    1518                 *addr_len = IP_ADDR;
    1519                 *prefix = 0;
    1520                 *suffix = 0;
    1521 
    1522                 for (index = ip_netifs_count(&ip_globals.netifs) - 1;
    1523                     index >= 0; index--) {
    1524                         netif = ip_netifs_get_index(&ip_globals.netifs, index);
    1525                         if (!netif)
    1526                                 continue;
    1527                        
    1528                         if (netif->packet_dimension.addr_len > *addr_len)
    1529                                 *addr_len = netif->packet_dimension.addr_len;
    1530                        
    1531                         if (netif->packet_dimension.prefix > *prefix)
    1532                                 *prefix = netif->packet_dimension.prefix;
    1533                                
    1534                         if (netif->packet_dimension.suffix > *suffix)
    1535                                 *suffix = netif->packet_dimension.suffix;
    1536                 }
    1537 
    1538                 *prefix = *prefix + IP_PREFIX;
    1539                 *suffix = *suffix + IP_SUFFIX;
    1540         } else {
    1541                 netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1542                 if (!netif) {
    1543                         fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    1544                         return ENOENT;
    1545                 }
    1546 
    1547                 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?
    1548                     netif->packet_dimension.addr_len : IP_ADDR;
    1549                 *prefix = netif->packet_dimension.prefix + IP_PREFIX;
    1550                 *suffix = netif->packet_dimension.suffix + IP_SUFFIX;
    1551         }
    1552         fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    1553 
    1554         return EOK;
    1555 }
    1556 
    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.
    1561  * @return              EOK on success.
    1562  * @return              ENOENT if device is not found.
    1563  */
    1564 static 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  */
    1588 static 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.
    1644  */
    1645 static int
    1646 ip_register(int protocol, services_t service, int phone,
    1647     tl_received_msg_t received_msg)
    1648 {
    1649         ip_proto_t *proto;
    1650         int index;
    1651 
    1652         if (!protocol || !service || ((phone < 0) && !received_msg))
    1653                 return EINVAL;
    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 
    1679 
    16801648static int
    16811649ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address,
     
    18771845}
    18781846
     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 */
     1863static 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
    18791876/** Processes the IP message.
    18801877 *
     
    18881885 *
    18891886 * @see ip_interface.h
    1890  * @see il_remote.h
     1887 * @see il_interface.h
    18911888 * @see IS_NET_IP_MESSAGE()
    18921889 */
    1893 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     1890int
     1891ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    18941892    size_t *answer_count)
    18951893{
    18961894        packet_t *packet;
    18971895        struct sockaddr *addr;
    1898         void *header;
    1899         size_t headerlen;
    19001896        size_t addrlen;
    19011897        size_t prefix;
    19021898        size_t suffix;
    19031899        size_t content;
     1900        void *header;
     1901        size_t headerlen;
    19041902        device_id_t device_id;
    19051903        int rc;
     
    19141912                    IPC_GET_PHONE(*call), NULL);
    19151913       
    1916         case NET_IP_DEVICE:
     1914        case NET_IL_DEVICE:
    19171915                return ip_device_req_local(0, IPC_GET_DEVICE(*call),
    19181916                    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);
    19191936       
    19201937        case NET_IP_RECEIVED_ERROR:
     
    19581975                return rc;
    19591976       
    1960         case NET_IP_PACKET_SPACE:
     1977        case NET_IL_PACKET_SPACE:
    19611978                rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen,
    19621979                    &prefix, &content, &suffix);
     
    19711988                return EOK;
    19721989       
    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;
     1990        case NET_IL_MTU_CHANGED:
     1991                return ip_mtu_changed_message(IPC_GET_DEVICE(*call),
     1992                    IPC_GET_MTU(*call));
     1993        }
     1994       
     1995        return ENOTSUP;
     1996}
     1997
     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 */
     2003static 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;
    19782014               
    1979                 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
    1980                     IPC_GET_ERROR(*call));
    1981         }
    1982        
    1983         return ENOTSUP;
    1984 }
    1985 
     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 */
    19862045int main(int argc, char *argv[])
    19872046{
     2047        int rc;
     2048       
    19882049        /* Start the module */
    1989         return il_module_start(SERVICE_IP);
     2050        rc = il_module_start_standalone(il_client_connection);
     2051        return rc;
    19902052}
    19912053
  • uspace/srv/net/il/ip/ip.h

    r8426912a r6610565b  
    138138/** IP global data. */
    139139struct ip_globals {
     140        /** Default client connection function for support modules. */
     141        async_client_conn_t client_connection;
    140142        /** Default gateway. */
    141143        ip_route_t gateway;
  • uspace/srv/net/net/net.c

    r8426912a r6610565b  
    4545#include <stdio.h>
    4646#include <str.h>
    47 #include <str_error.h>
    4847
    4948#include <ipc/ipc.h>
     
    5251#include <ipc/net_net.h>
    5352#include <ipc/il.h>
    54 #include <ipc/nil.h>
    5553
    5654#include <net/modules.h>
     
    6462
    6563#include <netif_remote.h>
    66 #include <nil_remote.h>
     64#include <nil_interface.h>
    6765#include <net_interface.h>
    6866#include <ip_interface.h>
     
    290288        if (rc != EOK)
    291289                return rc;
    292         rc = add_module(NULL, &net_globals.modules, (uint8_t *) NE2000_NAME,
    293             (uint8_t *) NE2000_FILENAME, SERVICE_NE2000, 0, connect_to_service);
     290        rc = add_module(NULL, &net_globals.modules, (uint8_t *) DP8390_NAME,
     291            (uint8_t *) DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service);
    294292        if (rc != EOK)
    295293                return rc;
     
    333331        if (rc != EOK)
    334332                return rc;
     333       
    335334       
    336335        rc = net_initialize(client_connection);
     
    592591                rc = start_device(netif);
    593592                if (rc != EOK) {
    594                         printf("%s: Error starting interface %s (%s)\n", NAME,
    595                             netif->name, str_error(rc));
    596593                        measured_strings_destroy(&netif->configuration);
    597594                        netifs_exclude_index(&net_globals.netifs, index);
    598                        
    599595                        return rc;
    600596                }
     
    713709int main(int argc, char *argv[])
    714710{
    715         return net_module_start(net_client_connection);
     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;
    716720}
    717721
  • uspace/srv/net/net/net.h

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

    r8426912a r6610565b  
    4848#include <packet_client.h>
    4949#include <net/device.h>
     50#include <nil_interface.h>
    5051#include <netif_skel.h>
    51 #include <nil_remote.h>
     52
     53/** Default hardware address. */
     54#define DEFAULT_ADDR  0
    5255
    5356/** Default address length. */
     
    5760#define NAME  "lo"
    5861
    59 static uint8_t default_addr[DEFAULT_ADDR_LEN] =
    60     {0, 0, 0, 0, 0, 0};
     62/** Network interface global data. */
     63netif_globals_t netif_globals;
    6164
    6265int netif_specific_message(ipc_callid_t callid, ipc_call_t *call,
     
    7174                return EBADMEM;
    7275       
    73         address->value = default_addr;
     76        uint8_t *addr = (uint8_t *) malloc(DEFAULT_ADDR_LEN);
     77        memset(addr, DEFAULT_ADDR, DEFAULT_ADDR_LEN);
     78       
     79        address->value = addr;
    7480        address->length = DEFAULT_ADDR_LEN;
    7581       
     
    7985int netif_get_device_stats(device_id_t device_id, device_stats_t *stats)
    8086{
     87        netif_device_t *device;
     88        int rc;
     89
    8190        if (!stats)
    8291                return EBADMEM;
    83        
    84         netif_device_t *device;
    85         int rc = find_device(device_id, &device);
     92
     93        rc = find_device(device_id, &device);
    8694        if (rc != EOK)
    8795                return rc;
    88        
     96
    8997        memcpy(stats, (device_stats_t *) device->specific,
    9098            sizeof(device_stats_t));
    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  */
    104 static void change_state_message(netif_device_t *device, device_state_t state)
     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 */
     110static int change_state_message(netif_device_t *device, device_state_t state)
    105111{
    106112        if (device->state != state) {
    107113                device->state = state;
    108114               
    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                 }
     115                printf("%s: State changed to %s\n", NAME,
     116                    (state == NETIF_ACTIVE) ? "active" : "stopped");
    120117               
    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  */
    135 static int lo_create(device_id_t device_id, netif_device_t **device)
    136 {
     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 */
     132static int create(device_id_t device_id, netif_device_t **device)
     133{
     134        int index;
     135
    137136        if (netif_device_map_count(&netif_globals.device_map) > 0)
    138137                return EXDEV;
    139        
     138
    140139        *device = (netif_device_t *) malloc(sizeof(netif_device_t));
    141140        if (!*device)
    142141                return ENOMEM;
    143        
     142
    144143        (*device)->specific = (device_stats_t *) malloc(sizeof(device_stats_t));
    145144        if (!(*device)->specific) {
     
    147146                return ENOMEM;
    148147        }
    149        
     148
    150149        null_device_stats((device_stats_t *) (*device)->specific);
    151150        (*device)->device_id = device_id;
    152151        (*device)->nil_phone = -1;
    153152        (*device)->state = NETIF_STOPPED;
    154         int index = netif_device_map_add(&netif_globals.device_map,
     153        index = netif_device_map_add(&netif_globals.device_map,
    155154            (*device)->device_id, *device);
    156        
     155
    157156        if (index < 0) {
    158157                free(*device);
     
    168167{
    169168        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        netif_device_t *device;
     176        int rc;
     177
    175178        /* Create a new device */
    176         netif_device_t *device;
    177         int rc = lo_create(device_id, &device);
     179        rc = create(device_id, &device);
    178180        if (rc != EOK)
    179181                return rc;
    180        
     182
     183        /* Print the settings */
    181184        printf("%s: Device created (id: %d)\n", NAME, device->device_id);
     185
    182186        return EOK;
    183187}
     
    186190{
    187191        netif_device_t *device;
    188         int rc = find_device(device_id, &device);
     192        size_t length;
     193        packet_t *next;
     194        int phone;
     195        int rc;
     196
     197        rc = find_device(device_id, &device);
    189198        if (rc != EOK)
    190199                return EOK;
    191        
     200
    192201        if (device->state != NETIF_ACTIVE) {
    193202                netif_pq_release(packet_get_id(packet));
    194203                return EFORWARD;
    195204        }
    196        
    197         packet_t *next = packet;
     205
     206        next = packet;
    198207        do {
    199208                ((device_stats_t *) device->specific)->send_packets++;
    200209                ((device_stats_t *) device->specific)->receive_packets++;
    201                 size_t length = packet_get_data_length(next);
     210                length = packet_get_data_length(next);
    202211                ((device_stats_t *) device->specific)->send_bytes += length;
    203212                ((device_stats_t *) device->specific)->receive_bytes += length;
    204213                next = pq_next(next);
    205         } while (next);
    206        
    207         int phone = device->nil_phone;
     214        } while(next);
     215
     216        phone = device->nil_phone;
    208217        fibril_rwlock_write_unlock(&netif_globals.lock);
    209        
    210218        nil_received_msg(phone, device_id, packet, sender);
    211        
    212219        fibril_rwlock_write_lock(&netif_globals.lock);
     220       
    213221        return EOK;
    214222}
     
    216224int netif_start_message(netif_device_t *device)
    217225{
    218         change_state_message(device, NETIF_ACTIVE);
    219         return device->state;
     226        return change_state_message(device, NETIF_ACTIVE);
    220227}
    221228
    222229int netif_stop_message(netif_device_t *device)
    223230{
    224         change_state_message(device, NETIF_STOPPED);
    225         return device->state;
     231        return change_state_message(device, NETIF_STOPPED);
    226232}
    227233
  • uspace/srv/net/nil/eth/Makefile

    r8426912a r6610565b  
    4242
    4343SOURCES = \
    44         eth.c
     44        eth.c \
     45        eth_module.c
    4546
    4647include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/nil/eth/eth.c

    r8426912a r6610565b  
    4545
    4646#include <ipc/ipc.h>
    47 #include <ipc/nil.h>
    4847#include <ipc/net.h>
    4948#include <ipc/services.h>
     
    5756#include <netif_remote.h>
    5857#include <net_interface.h>
    59 #include <il_remote.h>
     58#include <nil_interface.h>
     59#include <il_interface.h>
    6060#include <adt/measured_strings.h>
    6161#include <packet_client.h>
    6262#include <packet_remote.h>
    63 #include <nil_skel.h>
     63#include <nil_local.h>
    6464
    6565#include "eth.h"
     66#include "eth_header.h"
    6667
    6768/** The module name. */
     
    7172#define ETH_PREFIX \
    7273        (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \
    73             sizeof(eth_header_snap_t))
     74        sizeof(eth_header_snap_t))
    7475
    7576/** Reserved packet suffix length. */
    76 #define ETH_SUFFIX  (sizeof(eth_fcs_t))
     77#define ETH_SUFFIX \
     78        sizeof(eth_fcs_t)
    7779
    7880/** Maximum packet content length. */
    79 #define ETH_MAX_CONTENT  1500u
     81#define ETH_MAX_CONTENT 1500u
    8082
    8183/** Minimum packet content length. */
    82 #define ETH_MIN_CONTENT  46u
     84#define ETH_MIN_CONTENT 46u
    8385
    8486/** Maximum tagged packet content length. */
    8587#define ETH_MAX_TAGGED_CONTENT(flags) \
    8688        (ETH_MAX_CONTENT - \
    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))
     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))
    9092
    9193/** Minimum tagged packet content length. */
    9294#define ETH_MIN_TAGGED_CONTENT(flags) \
    9395        (ETH_MIN_CONTENT - \
    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))
     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))
    9799
    98100/** Dummy flag shift value. */
    99 #define ETH_DUMMY_SHIFT  0
     101#define ETH_DUMMY_SHIFT 0
    100102
    101103/** Mode flag shift value. */
    102 #define ETH_MODE_SHIFT  1
     104#define ETH_MODE_SHIFT  1
    103105
    104106/** Dummy device flag.
    105107 * Preamble and FCS are mandatory part of the packets.
    106108 */
    107 #define ETH_DUMMY  (1 << ETH_DUMMY_SHIFT)
     109#define ETH_DUMMY               (1 << ETH_DUMMY_SHIFT)
    108110
    109111/** Returns the dummy flag.
    110112 * @see ETH_DUMMY
    111113 */
    112 #define IS_DUMMY(flags)  ((flags) & ETH_DUMMY)
     114#define IS_DUMMY(flags)         ((flags) & ETH_DUMMY)
    113115
    114116/** Device mode flags.
     
    117119 * @see ETH_8023_2_SNAP
    118120 */
    119 #define ETH_MODE_MASK  (3 << ETH_MODE_SHIFT)
     121#define ETH_MODE_MASK           (3 << ETH_MODE_SHIFT)
    120122
    121123/** DIX Ethernet mode flag. */
    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.
     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.
    127129 * @see ETH_DIX
    128  *
    129  */
    130 #define IS_DIX(flags)  (((flags) & ETH_MODE_MASK) == ETH_DIX)
     130 */
     131#define IS_DIX(flags)           (((flags) & ETH_MODE_MASK) == ETH_DIX)
    131132
    132133/** 802.3 + 802.2 + LSAP mode flag. */
    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.
     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.
    138139 * @see ETH_8023_2_LSAP
    139  *
    140  */
    141 #define IS_8023_2_LSAP(flags)  (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP)
     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 /** Return whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.
    147  *
    148  * @param[in] flags Ethernet flags.
     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.
    149149 * @see ETH_8023_2_SNAP
    150  *
    151  */
    152 #define IS_8023_2_SNAP(flags)  (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP)
     150 */
     151#define IS_8023_2_SNAP(flags)   (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP)
    153152
    154153/** Type definition of the ethernet address type.
     
    247246                        rc = packet_translate_remote(eth_globals.net_phone,
    248247                            &packet, IPC_GET_PACKET(*icall));
    249                         if (rc == EOK)
     248                        if (rc == EOK) {
    250249                                rc = nil_received_msg_local(0,
    251250                                    IPC_GET_DEVICE(*icall), packet, 0);
    252                        
     251                        }
    253252                        ipc_answer_0(iid, (sysarg_t) rc);
    254253                        break;
     
    837836}
    838837
    839 int nil_module_message(ipc_callid_t callid, ipc_call_t *call,
    840     ipc_call_t *answer, size_t *answer_count)
     838int nil_message_standalone(const char *name, ipc_callid_t callid,
     839    ipc_call_t *call, ipc_call_t *answer, size_t *answer_count)
    841840{
    842841        measured_string_t *address;
     
    894893}
    895894
     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 */
     900static 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
    896936int main(int argc, char *argv[])
    897937{
     938        int rc;
     939       
    898940        /* Start the module */
    899         return nil_module_start(SERVICE_ETHERNET);
     941        rc = nil_module_start_standalone(nil_client_connection);
     942        return rc;
    900943}
    901944
  • uspace/srv/net/nil/eth/eth.h

    r8426912a r6610565b  
    4343#include <net/device.h>
    4444#include <adt/measured_strings.h>
    45 
    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  */
    61 typedef 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  */
    66 typedef struct eth_header_lsap eth_header_lsap_t;
    67 
    68 /** Type definition of the Ethernet header LSAP extension.
    69  * @see eth_ieee_lsap
    70  */
    71 typedef struct eth_ieee_lsap eth_ieee_lsap_t;
    72 
    73 /** Type definition of the Ethernet header SNAP extension.
    74  * @see eth_snap
    75  */
    76 typedef struct eth_snap eth_snap_t;
    77 
    78 /** Type definition of the Ethernet header preamble.
    79  * @see preamble
    80  */
    81 typedef struct eth_preamble eth_preamble_t;
    82 
    83 /** Type definition of the Ethernet header.
    84  * @see eth_header
    85  */
    86 typedef struct eth_header eth_header_t;
    87 
    88 /** Ethernet header Link Service Access Point extension. */
    89 struct 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. */
    110 struct 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  */
    125 struct 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. */
    141 struct 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. */
    155 struct 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. */
    171 struct 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. */
    190 typedef uint32_t eth_fcs_t;
    19145
    19246/** Type definition of the Ethernet global data.
  • uspace/srv/net/nil/nildummy/Makefile

    r8426912a r6610565b  
    4242
    4343SOURCES = \
    44         nildummy.c
     44        nildummy.c \
     45        nildummy_module.c
    4546
    4647include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/nil/nildummy/nildummy.c

    r8426912a r6610565b  
    4242#include <str.h>
    4343#include <ipc/ipc.h>
    44 #include <ipc/nil.h>
    4544#include <ipc/net.h>
    4645#include <ipc/services.h>
     
    4847#include <net/modules.h>
    4948#include <net/device.h>
    50 #include <il_remote.h>
     49#include <nil_interface.h>
     50#include <il_interface.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_skel.h>
     55#include <nil_local.h>
    5656
    5757#include "nildummy.h"
     
    8181int nil_initialize(int net_phone)
    8282{
     83        int rc;
     84       
    8385        fibril_rwlock_initialize(&nildummy_globals.devices_lock);
    8486        fibril_rwlock_initialize(&nildummy_globals.protos_lock);
     
    8890        nildummy_globals.net_phone = net_phone;
    8991        nildummy_globals.proto.phone = 0;
    90         int rc = nildummy_devices_initialize(&nildummy_globals.devices);
     92        rc = nildummy_devices_initialize(&nildummy_globals.devices);
    9193       
    9294        fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
     
    9698}
    9799
    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  *
     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.
    103105 */
    104106static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall)
     
    106108        packet_t *packet;
    107109        int rc;
    108        
     110
    109111        while (true) {
    110112                switch (IPC_GET_IMETHOD(*icall)) {
     
    118120                        rc = packet_translate_remote(nildummy_globals.net_phone,
    119121                            &packet, IPC_GET_PACKET(*icall));
    120                         if (rc == EOK)
     122                        if (rc == EOK) {
    121123                                rc = nil_received_msg_local(0,
    122124                                    IPC_GET_DEVICE(*icall), packet, 0);
    123                        
     125                        }
    124126                        ipc_answer_0(iid, (sysarg_t) rc);
    125127                        break;
     
    137139 * Determine the device local hardware address.
    138140 *
    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  *
     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.
    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
    155159        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
    156        
     160
    157161        /* An existing device? */
    158         nildummy_device_t *device =
    159             nildummy_devices_find(&nildummy_globals.devices, device_id);
     162        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    160163        if (device) {
    161164                if (device->service != service) {
     
    210213       
    211214        /* Get hardware address */
    212         int rc = netif_get_addr_req(device->phone, device->device_id,
    213             &device->addr, &device->addr_data);
     215        rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
     216            &device->addr_data);
    214217        if (rc != EOK) {
    215218                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     
    219222       
    220223        /* Add to the cache */
    221         int index = nildummy_devices_add(&nildummy_globals.devices,
     224        index = nildummy_devices_add(&nildummy_globals.devices,
    222225            device->device_id, device);
    223226        if (index < 0) {
     
    237240/** Return the device hardware address.
    238241 *
    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.
     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.
    245247 *
    246248 */
     
    248250    measured_string_t **address)
    249251{
     252        nildummy_device_t *device;
     253
    250254        if (!address)
    251255                return EBADMEM;
    252256       
    253257        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    254        
    255         nildummy_device_t *device =
    256             nildummy_devices_find(&nildummy_globals.devices, device_id);
     258        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    257259        if (!device) {
    258260                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    259261                return ENOENT;
    260262        }
    261        
    262263        *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 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.
     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.
    280279 *
    281280 */
     
    283282    size_t *prefix, size_t *content, size_t *suffix)
    284283{
    285         if ((!addr_len) || (!prefix) || (!content) || (!suffix))
     284        nildummy_device_t *device;
     285
     286        if (!addr_len || !prefix || !content || !suffix)
    286287                return EBADMEM;
    287288       
    288289        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    289        
    290         nildummy_device_t *device =
    291             nildummy_devices_find(&nildummy_globals.devices, device_id);
     290        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    292291        if (!device) {
    293292                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    294293                return ENOENT;
    295294        }
    296        
     295
    297296        *content = device->mtu;
    298        
    299297        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    300298       
     
    308306    packet_t *packet, services_t target)
    309307{
     308        packet_t *next;
     309
    310310        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    311        
    312311        if (nildummy_globals.proto.phone) {
    313312                do {
    314                         packet_t *next = pq_detach(packet);
     313                        next = pq_detach(packet);
    315314                        il_received_msg(nildummy_globals.proto.phone, device_id,
    316315                            packet, nildummy_globals.proto.service);
    317316                        packet = next;
    318                 } while (packet);
    319         }
    320        
     317                } while(packet);
     318        }
    321319        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    322320       
     
    328326 * Pass received packets for this service.
    329327 *
    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  *
     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.
    337333 */
    338334static int nildummy_register_message(services_t service, int phone)
     
    351347/** Send the packet queue.
    352348 *
    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  *
     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.
    361355 */
    362356static int nildummy_send_message(device_id_t device_id, packet_t *packet,
    363357    services_t sender)
    364358{
     359        nildummy_device_t *device;
     360
    365361        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    366        
    367         nildummy_device_t *device =
    368             nildummy_devices_find(&nildummy_globals.devices, device_id);
     362        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    369363        if (!device) {
    370364                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    371365                return ENOENT;
    372366        }
    373        
     367
    374368        /* Send packet queue */
    375369        if (packet)
    376370                netif_send_msg(device->phone, device_id, packet,
    377371                    SERVICE_NILDUMMY);
    378        
    379372        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    380        
    381         return EOK;
    382 }
    383 
    384 int nil_module_message(ipc_callid_t callid, ipc_call_t *call,
    385     ipc_call_t *answer, size_t *answer_count)
     373        return EOK;
     374}
     375
     376int nil_message_standalone(const char *name, ipc_callid_t callid,
     377    ipc_call_t *call, ipc_call_t *answer, size_t *answer_count)
    386378{
    387379        measured_string_t *address;
     
    442434}
    443435
     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 */
     441static 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
    444477int main(int argc, char *argv[])
    445478{
     479        int rc;
     480       
    446481        /* Start the module */
    447         return nil_module_start(SERVICE_NILDUMMY);
     482        rc = nil_module_start_standalone(nil_client_connection);
     483        return rc;
    448484}
    449485
  • uspace/srv/net/nil/nildummy/nildummy.h

    r8426912a r6610565b  
    4545
    4646/** Type definition of the dummy nil global data.
    47  *
    4847 * @see nildummy_globals
    49  *
    5048 */
    5149typedef struct nildummy_globals nildummy_globals_t;
    5250
    5351/** Type definition of the dummy nil device specific data.
    54  *
    5552 * @see nildummy_device
    56  *
    5753 */
    5854typedef struct nildummy_device nildummy_device_t;
    5955
    6056/** Type definition of the dummy nil protocol specific data.
    61  *
    6257 * @see nildummy_proto
    63  *
    6458 */
    6559typedef struct nildummy_proto nildummy_proto_t;
    6660
    6761/** Dummy nil device map.
    68  *
    69  * Map devices to the dummy nil device specific data.
     62 * Maps devices to the dummy nil device specific data.
    7063 * @see device.h
    71  *
    7264 */
    7365DEVICE_MAP_DECLARE(nildummy_devices, nildummy_device_t);
     
    7769        /** Device identifier. */
    7870        device_id_t device_id;
    79        
    8071        /** Device driver service. */
    8172        services_t service;
    82        
    8373        /** Driver phone. */
    8474        int phone;
    85        
    8675        /** Maximal transmission unit. */
    8776        size_t mtu;
    88        
    8977        /** Actual device hardware address. */
    9078        measured_string_t *addr;
    91        
    9279        /** Actual device hardware address data. */
    9380        uint8_t *addr_data;
     
    9885        /** Protocol service. */
    9986        services_t service;
    100        
    10187        /** Protocol module phone. */
    10288        int phone;
     
    10793        /** Networking module phone. */
    10894        int net_phone;
    109        
    110         /** Lock for devices. */
     95        /** Safety lock for devices. */
    11196        fibril_rwlock_t devices_lock;
    112        
    11397        /** All known Ethernet devices. */
    11498        nildummy_devices_t devices;
    115        
    11699        /** Safety lock for protocols. */
    117100        fibril_rwlock_t protos_lock;
    118        
    119101        /** Default protocol. */
    120102        nildummy_proto_t proto;
  • uspace/srv/net/tl/icmp/Makefile

    r8426912a r6610565b  
    3434
    3535SOURCES = \
    36         icmp.c
     36        icmp.c \
     37        icmp_module.c
    3738
    3839include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/tl/icmp/icmp.c

    r8426912a r6610565b  
    3535 * @see icmp.h
    3636 */
     37
     38#include "icmp.h"
     39#include "icmp_module.h"
    3740
    3841#include <async.h>
     
    6568#include <icmp_client.h>
    6669#include <icmp_interface.h>
    67 #include <il_remote.h>
     70#include <il_interface.h>
    6871#include <ip_client.h>
    6972#include <ip_interface.h>
    7073#include <net_interface.h>
    71 #include <tl_remote.h>
    72 #include <tl_skel.h>
     74#include <tl_interface.h>
     75#include <tl_local.h>
    7376#include <icmp_header.h>
    7477
    75 #include "icmp.h"
    76 
    7778/** ICMP module name. */
    78 #define NAME  "icmp"
     79#define NAME    "ICMP protocol"
    7980
    8081/** Default ICMP error reporting. */
     
    391392        return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header,
    392393            SERVICE_ICMP, 0, 0, 0);
     394}
     395
     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 */
     403int 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;
    393468}
    394469
     
    592667                return icmp_release_and_return(packet, rc);
    593668
    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  */
    603 static 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  */
    635 int 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);
    700669        return EOK;
    701670}
     
    924893 * @see IS_NET_ICMP_MESSAGE()
    925894 */
    926 int tl_module_message   (ipc_callid_t callid, ipc_call_t *call,
     895int icmp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    927896    ipc_call_t *answer, size_t *answer_count)
    928897{
     898        packet_t *packet;
     899        int rc;
     900
    929901        *answer_count = 0;
    930902        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       
    931911        case NET_ICMP_INIT:
    932912                return icmp_process_client_messages(callid, *call);
     913       
    933914        default:
    934915                return icmp_process_message(call);
    935916        }
     917
     918        return ENOTSUP;
     919}
     920
     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 */
     928static 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);
    936935       
    937         return ENOTSUP;
    938 }
    939 
     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 */
    940970int main(int argc, char *argv[])
    941971{
     972        int rc;
     973       
    942974        /* Start the module */
    943         return tl_module_start(SERVICE_ICMP);
     975        rc = tl_module_start_standalone(tl_client_connection);
     976        return rc;
    944977}
    945978
    946979/** @}
    947980 */
     981
  • uspace/srv/net/tl/tcp/Makefile

    r8426912a r6610565b  
    3434
    3535SOURCES = \
    36         tcp.c
     36        tcp.c \
     37        tcp_module.c
    3738
    3839include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/tl/tcp/tcp.c

    r8426912a r6610565b  
    3636 */
    3737
     38#include "tcp.h"
     39#include "tcp_header.h"
     40#include "tcp_module.h"
     41
    3842#include <assert.h>
    3943#include <async.h>
     
    6872#include <socket_core.h>
    6973#include <tl_common.h>
    70 #include <tl_remote.h>
    71 #include <tl_skel.h>
    72 
    73 #include "tcp.h"
    74 #include "tcp_header.h"
     74#include <tl_local.h>
     75#include <tl_interface.h>
    7576
    7677/** TCP module name. */
    77 #define NAME  "tcp"
     78#define NAME    "TCP protocol"
    7879
    7980/** The TCP window default value. */
     
    219220/** TCP global data. */
    220221tcp_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 */
     230int 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
     260out:
     261        fibril_rwlock_write_unlock(&tcp_globals.lock);
     262        return rc;
     263}
    221264
    222265int tcp_received_msg(device_id_t device_id, packet_t *packet,
     
    12171260 * @see IS_NET_TCP_MESSAGE()
    12181261 */
    1219 int tl_module_message(ipc_callid_t callid, ipc_call_t *call,
     1262int
     1263tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    12201264    ipc_call_t *answer, size_t *answer_count)
    12211265{
     1266        packet_t *packet;
     1267        int rc;
     1268
    12221269        assert(call);
    12231270        assert(answer);
     
    12261273        *answer_count = 0;
    12271274        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;
    12281287        case IPC_M_CONNECT_TO_ME:
    12291288                return tcp_process_client_messages(callid, *call);
     
    24272486}
    24282487
    2429 /** Process IPC messages from the IP module
     2488/** Default thread for new connections.
    24302489 *
    2431  * @param[in]     iid   Message identifier.
    2432  * @param[in,out] icall Message parameters.
     2490 * @param[in] iid       The initial message identifier.
     2491 * @param[in] icall     The initial message call structure.
    24332492 *
    24342493 */
    2435 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall)
    2436 {
    2437         packet_t *packet;
     2494static 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
     2502        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.
     2533 *
     2534 * @return              EOK on success.
     2535 * @return              Other error codes as defined for each specific module
     2536 *                      start function.
     2537 */
     2538int
     2539main(int argc, char *argv[])
     2540{
    24382541        int rc;
    2439        
    2440         while (true) {
    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.
    2460  *
    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  *
    2466  */
    2467 int 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 
    2495 out:
    2496         fibril_rwlock_write_unlock(&tcp_globals.lock);
     2542
     2543        rc = tl_module_start_standalone(tl_client_connection);
    24972544        return rc;
    2498 }
    2499 
    2500 int main(int argc, char *argv[])
    2501 {
    2502         return tl_module_start(SERVICE_TCP);
    25032545}
    25042546
  • uspace/srv/net/tl/udp/Makefile

    r8426912a r6610565b  
    3434
    3535SOURCES = \
    36         udp.c
     36        udp.c \
     37        udp_module.c
    3738
    3839include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/tl/udp/udp.c

    r8426912a r6610565b  
    3535 * @see udp.h
    3636 */
     37
     38#include "udp.h"
     39#include "udp_header.h"
     40#include "udp_module.h"
    3741
    3842#include <async.h>
     
    6569#include <socket_core.h>
    6670#include <tl_common.h>
    67 #include <tl_remote.h>
    68 #include <tl_skel.h>
    69 
    70 #include "udp.h"
    71 #include "udp_header.h"
     71#include <tl_local.h>
     72#include <tl_interface.h>
    7273
    7374/** UDP module name. */
    74 #define NAME  "udp"
     75#define NAME    "UDP protocol"
    7576
    7677/** Default UDP checksum computing. */
     
    9192/** UDP global data.  */
    9293udp_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 */
     102int 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}
    93185
    94186/** Releases the packet and returns the result.
     
    334426}
    335427
    336 /** Process IPC messages from the IP module
    337  *
    338  * @param[in]     iid   Message identifier.
    339  * @param[in,out] icall Message parameters.
    340  *
    341  */
    342 static 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  */
    374 int 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 
    459428/** Sends data from the socket to the remote address.
    460429 *
     
    891860 * @see IS_NET_UDP_MESSAGE()
    892861 */
    893 int tl_module_message(ipc_callid_t callid, ipc_call_t *call,
     862int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    894863    ipc_call_t *answer, size_t *answer_count)
    895864{
     865        packet_t *packet;
     866        int rc;
     867
    896868        *answer_count = 0;
    897869
    898870        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));
    899878        case IPC_M_CONNECT_TO_ME:
    900879                return udp_process_client_messages(callid, *call);
     
    904883}
    905884
     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 */
     890static 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 */
    906932int main(int argc, char *argv[])
    907933{
     934        int rc;
     935       
    908936        /* Start the module */
    909         return tl_module_start(SERVICE_UDP);
     937        rc = tl_module_start_standalone(tl_client_connection);
     938        return rc;
    910939}
    911940
Note: See TracChangeset for help on using the changeset viewer.