Changeset 797b704 in mainline


Ignore:
Timestamp:
2011-01-12T14:40:09Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
014dd57b
Parents:
73ac2e9
Message:

streamline internetworking layer

  • IPC method renaming

NET_IL_DEVICE → NET_IP_DEVICE
NET_IL_PACKET_SPACE → NET_IP_PACKET_SPACE
NET_IL_SEND → NET_IP_SEND

The original methods were actually not generic methods of the IL layer (used by the lower layers), but specific methods of the IP module
and used by the higher layers. The original naming was rather confusing.

  • implelement common IL module skeleton
  • small improvements in the comments of the NETIF and NIL skeletons
  • IL modules now use a separate receiver function for the NET_IL_* calls
Location:
uspace
Files:
1 added
6 deleted
15 edited
3 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/include/ipc/il.h

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

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

    r73ac2e9 r797b704  
    4444        nil/nil_remote.c \
    4545        nil/nil_skel.c \
    46         il/il_interface.c \
     46        il/il_remote.c \
     47        il/il_skel.c \
    4748        il/ip_remote.c \
    4849        il/ip_client.c \
  • uspace/lib/net/il/il_remote.c

    r73ac2e9 r797b704  
    3333/** @file
    3434 * Internetwork layer module interface for the underlying network interface
    35  * layer. This interface is always called by the remote modules.
     35 * layer.
    3636 */
    3737
    38 #include <il_interface.h>
     38#include <il_remote.h>
    3939#include <generic.h>
    4040#include <packet_client.h>
  • uspace/lib/net/il/ip_remote.c

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

    r73ac2e9 r797b704  
    3636 */
    3737
    38 #ifndef LIBNET_IL_INTERFACE_H_
    39 #define LIBNET_IL_INTERFACE_H_
     38#ifndef LIBNET_IL_REMOTE_H_
     39#define LIBNET_IL_REMOTE_H_
    4040
    4141#include <ipc/services.h>
  • uspace/lib/net/include/il_skel.h

    r73ac2e9 r797b704  
    2727 */
    2828
    29 /** @addtogroup libnet 
     29/** @addtogroup libnet
    3030 * @{
    3131 */
    3232
    33 #ifndef LIBNET_IL_LOCAL_H_
    34 #define LIBNET_IL_LOCAL_H_
     33#ifndef LIBNET_IL_SKEL_H_
     34#define LIBNET_IL_SKEL_H_
    3535
     36/** @file
     37 * Internetwork layer module skeleton.
     38 * The skeleton has to be part of each internetwork layer module.
     39 */
     40
     41#include <async.h>
     42#include <fibril_synch.h>
    3643#include <ipc/ipc.h>
    37 #include <async.h>
     44#include <ipc/services.h>
    3845
    39 /** Processes the Internet layer module message.
     46#include <adt/measured_strings.h>
     47#include <net/device.h>
     48#include <net/packet.h>
     49
     50/** Module initialization.
    4051 *
    41  * @param[in]           callid The message identifier.
    42  * @param[in]           call The message parameters.
    43  * @param[out]          answer The message answer parameters.
    44  * @param[out]          answer_count The last parameter for the actual answer in
    45  *                      the answer parameter.
    46  * @return              EOK on success.
    47  * @return              Other error codes as defined for the arp_message()
    48  *                      function.
     52 * This has to be implemented in user code.
     53 *
     54 * @param[in] net_phone Networking module phone.
     55 *
     56 * @return EOK on success.
     57 * @return Other error codes as defined for each specific module
     58 *         initialize function.
     59 *
     60 */
     61extern int il_initialize(int net_phone);
     62
     63/** Process the Internet layer module message.
     64 *
     65 * This has to be implemented in user code.
     66 *
     67 * @param[in]  callid Message identifier.
     68 * @param[in]  call   Message parameters.
     69 * @param[out] answer Answer.
     70 * @param[out] count  Number of arguments of the answer.
     71 *
     72 * @return EOK on success.
     73 * @return Other error codes as defined for the arp_message()
     74 *         function.
     75 *
    4976 */
    5077extern int il_module_message(ipc_callid_t callid, ipc_call_t *call,
    5178    ipc_call_t *answer, size_t *answer_count);
    5279
    53 /** Starts the Internet layer module.
    54  *
    55  * Initializes the client connection servicing function, initializes the module,
    56  * registers the module service and starts the async manager, processing IPC
    57  * messages in an infinite loop.
    58  *
    59  * @param[in] client_connection The client connection processing function. The
    60  *                      module skeleton propagates its own one.
    61  * @return              EOK on successful module termination.
    62  * @return              Other error codes as defined for the arp_initialize()
    63  *                      function.
    64  * @return              Other error codes as defined for the REGISTER_ME() macro
    65  *                      function.
    66  */
    67 extern int il_module_start(async_client_conn_t client_connection);
     80extern int il_module_start(int);
    6881
    6982#endif
  • uspace/lib/net/include/nil_skel.h

    r73ac2e9 r797b704  
    5050/** Module initialization.
    5151 *
    52  * Is called by the module_start() function.
     52 * This has to be implemented in user code.
    5353 *
    5454 * @param[in] net_phone Networking module phone.
     
    5959 *
    6060 */
    61 extern int nil_initialize(int);
     61extern int nil_initialize(int net_phone);
    6262
    6363/** Notify the network interface layer about the device state change.
     64 *
     65 * This has to be implemented in user code.
    6466 *
    6567 * @param[in] nil_phone Network interface layer phone.
     
    7981 * upper layers.
    8082 *
     83 * This has to be implemented in user code.
     84 *
    8185 * @param[in] nil_phone Network interface layer phone.
    8286 * @param[in] device_id Source device identifier.
     
    9296
    9397/** Message processing function.
     98 *
     99 * This has to be implemented in user code.
    94100 *
    95101 * @param[in]  name   Module name.
  • uspace/lib/net/nil/nil_skel.c

    r73ac2e9 r797b704  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2011 Martin Decky
    33 * All rights reserved.
    44 *
     
    3232
    3333/** @file
    34  * Network network interface layer module implementation.
     34 * Network interface layer module skeleton implementation.
    3535 * @see nil_skel.h
    3636 */
  • uspace/srv/net/il/arp/Makefile

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

    r73ac2e9 r797b704  
    3535 * @see arp.h
    3636 */
    37 
    38 #include "arp.h"
    39 #include "arp_header.h"
    40 #include "arp_oc.h"
    41 #include "arp_module.h"
    4237
    4338#include <async.h>
     
    6459#include <packet_client.h>
    6560#include <packet_remote.h>
    66 #include <il_interface.h>
    67 #include <il_local.h>
    68 
     61#include <il_remote.h>
     62#include <il_skel.h>
     63#include "arp.h"
    6964
    7065/** ARP module name. */
     
    7368/** Number of microseconds to wait for an ARP reply. */
    7469#define ARP_TRANS_WAIT  1000000
     70
     71/** @name ARP operation codes definitions */
     72/*@{*/
     73
     74/** REQUEST operation code. */
     75#define ARPOP_REQUEST  1
     76
     77/** REPLY operation code. */
     78#define ARPOP_REPLY  2
     79
     80/*@}*/
     81
     82/** Type definition of an ARP protocol header.
     83 * @see arp_header
     84 */
     85typedef struct arp_header arp_header_t;
     86
     87/** ARP protocol header. */
     88struct arp_header {
     89        /**
     90         * Hardware type identifier.
     91         * @see hardware.h
     92         */
     93        uint16_t hardware;
     94       
     95        /** Protocol identifier. */
     96        uint16_t protocol;
     97        /** Hardware address length in bytes. */
     98        uint8_t hardware_length;
     99        /** Protocol address length in bytes. */
     100        uint8_t protocol_length;
     101       
     102        /**
     103         * ARP packet type.
     104         * @see arp_oc.h
     105         */
     106        uint16_t operation;
     107} __attribute__ ((packed));
    75108
    76109/** ARP global data. */
     
    231264       
    232265        return EOK;
     266}
     267
     268/** Process the received ARP packet.
     269 *
     270 * Update the source hardware address if the source entry exists or the packet
     271 * is targeted to my protocol address.
     272 *
     273 * Respond to the ARP request if the packet is the ARP request and is
     274 * targeted to my address.
     275 *
     276 * @param[in]     device_id Source device identifier.
     277 * @param[in,out] packet    Received packet.
     278 *
     279 * @return EOK on success and the packet is no longer needed.
     280 * @return One on success and the packet has been reused.
     281 * @return EINVAL if the packet is too small to carry an ARP
     282 *         packet.
     283 * @return EINVAL if the received address lengths differs from
     284 *         the registered values.
     285 * @return ENOENT if the device is not found in the cache.
     286 * @return ENOENT if the protocol for the device is not found in
     287 *         the cache.
     288 * @return ENOMEM if there is not enough memory left.
     289 *
     290 */
     291static int arp_receive_message(device_id_t device_id, packet_t *packet)
     292{
     293        int rc;
     294       
     295        size_t length = packet_get_data_length(packet);
     296        if (length <= sizeof(arp_header_t))
     297                return EINVAL;
     298       
     299        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     300        if (!device)
     301                return ENOENT;
     302       
     303        arp_header_t *header = (arp_header_t *) packet_get_data(packet);
     304        if ((ntohs(header->hardware) != device->hardware) ||
     305            (length < sizeof(arp_header_t) + header->hardware_length * 2U +
     306            header->protocol_length * 2U)) {
     307                return EINVAL;
     308        }
     309       
     310        arp_proto_t *proto = arp_protos_find(&device->protos,
     311            protocol_unmap(device->service, ntohs(header->protocol)));
     312        if (!proto)
     313                return ENOENT;
     314       
     315        uint8_t *src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
     316        uint8_t *src_proto = src_hw + header->hardware_length;
     317        uint8_t *des_hw = src_proto + header->protocol_length;
     318        uint8_t *des_proto = des_hw + header->hardware_length;
     319       
     320        arp_trans_t *trans = arp_addr_find(&proto->addresses, src_proto,
     321            header->protocol_length);
     322       
     323        if ((trans) && (trans->hw_addr)) {
     324                /* Translation exists */
     325                if (trans->hw_addr->length != header->hardware_length)
     326                        return EINVAL;
     327               
     328                memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
     329        }
     330       
     331        /* Is my protocol address? */
     332        if (proto->addr->length != header->protocol_length)
     333                return EINVAL;
     334       
     335        if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
     336                if (!trans) {
     337                        /* Update the translation */
     338                        trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
     339                        if (!trans)
     340                                return ENOMEM;
     341                       
     342                        trans->hw_addr = NULL;
     343                        fibril_condvar_initialize(&trans->cv);
     344                        rc = arp_addr_add(&proto->addresses, src_proto,
     345                            header->protocol_length, trans);
     346                        if (rc != EOK) {
     347                                /* The generic char map has already freed trans! */
     348                                return rc;
     349                        }
     350                }
     351               
     352                if (!trans->hw_addr) {
     353                        trans->hw_addr = measured_string_create_bulk(src_hw,
     354                            header->hardware_length);
     355                        if (!trans->hw_addr)
     356                                return ENOMEM;
     357                       
     358                        /* Notify the fibrils that wait for the translation. */
     359                        fibril_condvar_broadcast(&trans->cv);
     360                }
     361               
     362                if (ntohs(header->operation) == ARPOP_REQUEST) {
     363                        header->operation = htons(ARPOP_REPLY);
     364                        memcpy(des_proto, src_proto, header->protocol_length);
     365                        memcpy(src_proto, proto->addr->value,
     366                            header->protocol_length);
     367                        memcpy(src_hw, device->addr->value,
     368                            device->packet_dimension.addr_len);
     369                        memcpy(des_hw, trans->hw_addr->value,
     370                            header->hardware_length);
     371                       
     372                        rc = packet_set_addr(packet, src_hw, des_hw,
     373                            header->hardware_length);
     374                        if (rc != EOK)
     375                                return rc;
     376                       
     377                        nil_send_msg(device->phone, device_id, packet,
     378                            SERVICE_ARP);
     379                        return 1;
     380                }
     381        }
     382       
     383        return EOK;
     384}
     385
     386/** Update the device content length according to the new MTU value.
     387 *
     388 * @param[in] device_id Device identifier.
     389 * @param[in] mtu       New MTU value.
     390 *
     391 * @return ENOENT if device is not found.
     392 * @return EOK on success.
     393 *
     394 */
     395static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
     396{
     397        fibril_mutex_lock(&arp_globals.lock);
     398       
     399        arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
     400        if (!device) {
     401                fibril_mutex_unlock(&arp_globals.lock);
     402                return ENOENT;
     403        }
     404       
     405        device->packet_dimension.content = mtu;
     406       
     407        fibril_mutex_unlock(&arp_globals.lock);
     408       
     409        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
     410       
     411        return EOK;
     412}
     413
     414/** Process IPC messages from the registered device driver modules
     415 *
     416 * @param[in]     iid   Message identifier.
     417 * @param[in,out] icall Message parameters.
     418 *
     419 */
     420static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     421{
     422        packet_t *packet;
     423        int rc;
     424       
     425        while (true) {
     426                switch (IPC_GET_IMETHOD(*icall)) {
     427                case NET_IL_DEVICE_STATE:
     428                        /* Do nothing - keep the cache */
     429                        ipc_answer_0(iid, (sysarg_t) EOK);
     430                        break;
     431               
     432                case NET_IL_RECEIVED:
     433                        rc = packet_translate_remote(arp_globals.net_phone, &packet,
     434                            IPC_GET_PACKET(*icall));
     435                        if (rc == EOK) {
     436                                fibril_mutex_lock(&arp_globals.lock);
     437                                do {
     438                                        packet_t *next = pq_detach(packet);
     439                                        rc = arp_receive_message(IPC_GET_DEVICE(*icall), packet);
     440                                        if (rc != 1) {
     441                                                pq_release_remote(arp_globals.net_phone,
     442                                                    packet_get_id(packet));
     443                                        }
     444                                       
     445                                        packet = next;
     446                                } while (packet);
     447                                fibril_mutex_unlock(&arp_globals.lock);
     448                        }
     449                        ipc_answer_0(iid, (sysarg_t) rc);
     450                        break;
     451               
     452                case NET_IL_MTU_CHANGED:
     453                        rc = arp_mtu_changed_message(IPC_GET_DEVICE(*icall),
     454                            IPC_GET_MTU(*icall));
     455                        ipc_answer_0(iid, (sysarg_t) rc);
     456                        break;
     457               
     458                default:
     459                        ipc_answer_0(iid, (sysarg_t) ENOTSUP);
     460                }
     461               
     462                iid = async_get_call(icall);
     463        }
    233464}
    234465
     
    335566                device->phone = nil_bind_service(device->service,
    336567                    (sysarg_t) device->device_id, SERVICE_ARP,
    337                     arp_globals.client_connection);
     568                    arp_receiver);
    338569                if (device->phone < 0) {
    339570                        fibril_mutex_unlock(&arp_globals.lock);
     
    396627}
    397628
    398 /** Initialize the ARP module.
    399  *
    400  *  @param[in] client_connection The client connection processing function.
    401  *                               The module skeleton propagates its own one.
    402  *
    403  *  @return EOK on success.
    404  *  @return ENOMEM if there is not enough memory left.
    405  *
    406  */
    407 int arp_initialize(async_client_conn_t client_connection)
     629int il_initialize(int net_phone)
    408630{
    409631        fibril_mutex_initialize(&arp_globals.lock);
    410632       
    411633        fibril_mutex_lock(&arp_globals.lock);
    412         arp_globals.client_connection = client_connection;
     634        arp_globals.net_phone = net_phone;
    413635        int rc = arp_cache_initialize(&arp_globals.cache);
    414636        fibril_mutex_unlock(&arp_globals.lock);
    415637       
    416638        return rc;
    417 }
    418 
    419 /** Update the device content length according to the new MTU value.
    420  *
    421  * @param[in] device_id Device identifier.
    422  * @param[in] mtu       New MTU value.
    423  *
    424  * @return ENOENT if device is not found.
    425  * @return EOK on success.
    426  *
    427  */
    428 static int arp_mtu_changed_message(device_id_t device_id, size_t mtu)
    429 {
    430         fibril_mutex_lock(&arp_globals.lock);
    431        
    432         arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    433         if (!device) {
    434                 fibril_mutex_unlock(&arp_globals.lock);
    435                 return ENOENT;
    436         }
    437        
    438         device->packet_dimension.content = mtu;
    439        
    440         fibril_mutex_unlock(&arp_globals.lock);
    441        
    442         printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
    443        
    444         return EOK;
    445 }
    446 
    447 /** Process the received ARP packet.
    448  *
    449  * Update the source hardware address if the source entry exists or the packet
    450  * is targeted to my protocol address.
    451  *
    452  * Respond to the ARP request if the packet is the ARP request and is
    453  * targeted to my address.
    454  *
    455  * @param[in]     device_id Source device identifier.
    456  * @param[in,out] packet    Received packet.
    457  *
    458  * @return EOK on success and the packet is no longer needed.
    459  * @return One on success and the packet has been reused.
    460  * @return EINVAL if the packet is too small to carry an ARP
    461  *         packet.
    462  * @return EINVAL if the received address lengths differs from
    463  *         the registered values.
    464  * @return ENOENT if the device is not found in the cache.
    465  * @return ENOENT if the protocol for the device is not found in
    466  *         the cache.
    467  * @return ENOMEM if there is not enough memory left.
    468  *
    469  */
    470 static int arp_receive_message(device_id_t device_id, packet_t *packet)
    471 {
    472         int rc;
    473        
    474         size_t length = packet_get_data_length(packet);
    475         if (length <= sizeof(arp_header_t))
    476                 return EINVAL;
    477        
    478         arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);
    479         if (!device)
    480                 return ENOENT;
    481        
    482         arp_header_t *header = (arp_header_t *) packet_get_data(packet);
    483         if ((ntohs(header->hardware) != device->hardware) ||
    484             (length < sizeof(arp_header_t) + header->hardware_length * 2U +
    485             header->protocol_length * 2U)) {
    486                 return EINVAL;
    487         }
    488        
    489         arp_proto_t *proto = arp_protos_find(&device->protos,
    490             protocol_unmap(device->service, ntohs(header->protocol)));
    491         if (!proto)
    492                 return ENOENT;
    493        
    494         uint8_t *src_hw = ((uint8_t *) header) + sizeof(arp_header_t);
    495         uint8_t *src_proto = src_hw + header->hardware_length;
    496         uint8_t *des_hw = src_proto + header->protocol_length;
    497         uint8_t *des_proto = des_hw + header->hardware_length;
    498        
    499         arp_trans_t *trans = arp_addr_find(&proto->addresses, src_proto,
    500             header->protocol_length);
    501        
    502         if ((trans) && (trans->hw_addr)) {
    503                 /* Translation exists */
    504                 if (trans->hw_addr->length != header->hardware_length)
    505                         return EINVAL;
    506                
    507                 memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length);
    508         }
    509        
    510         /* Is my protocol address? */
    511         if (proto->addr->length != header->protocol_length)
    512                 return EINVAL;
    513        
    514         if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) {
    515                 if (!trans) {
    516                         /* Update the translation */
    517                         trans = (arp_trans_t *) malloc(sizeof(arp_trans_t));
    518                         if (!trans)
    519                                 return ENOMEM;
    520                        
    521                         trans->hw_addr = NULL;
    522                         fibril_condvar_initialize(&trans->cv);
    523                         rc = arp_addr_add(&proto->addresses, src_proto,
    524                             header->protocol_length, trans);
    525                         if (rc != EOK) {
    526                                 /* The generic char map has already freed trans! */
    527                                 return rc;
    528                         }
    529                 }
    530                
    531                 if (!trans->hw_addr) {
    532                         trans->hw_addr = measured_string_create_bulk(src_hw,
    533                             header->hardware_length);
    534                         if (!trans->hw_addr)
    535                                 return ENOMEM;
    536                        
    537                         /* Notify the fibrils that wait for the translation. */
    538                         fibril_condvar_broadcast(&trans->cv);
    539                 }
    540                
    541                 if (ntohs(header->operation) == ARPOP_REQUEST) {
    542                         header->operation = htons(ARPOP_REPLY);
    543                         memcpy(des_proto, src_proto, header->protocol_length);
    544                         memcpy(src_proto, proto->addr->value,
    545                             header->protocol_length);
    546                         memcpy(src_hw, device->addr->value,
    547                             device->packet_dimension.addr_len);
    548                         memcpy(des_hw, trans->hw_addr->value,
    549                             header->hardware_length);
    550                        
    551                         rc = packet_set_addr(packet, src_hw, des_hw,
    552                             header->hardware_length);
    553                         if (rc != EOK)
    554                                 return rc;
    555                        
    556                         nil_send_msg(device->phone, device_id, packet,
    557                             SERVICE_ARP);
    558                         return 1;
    559                 }
    560         }
    561        
    562         return EOK;
    563639}
    564640
     
    714790 *
    715791 */
    716 int arp_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     792int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    717793    size_t *count)
    718794{
     
    720796        measured_string_t *translation;
    721797        uint8_t *data;
    722         packet_t *packet;
    723         packet_t *next;
    724798        int rc;
    725799       
     
    784858        case NET_ARP_CLEAN_CACHE:
    785859                return arp_clean_cache_req(0);
    786        
    787         case NET_IL_DEVICE_STATE:
    788                 /* Do nothing - keep the cache */
    789                 return EOK;
    790        
    791         case NET_IL_RECEIVED:
    792                
    793                 rc = packet_translate_remote(arp_globals.net_phone, &packet,
    794                     IPC_GET_PACKET(*call));
    795                 if (rc != EOK)
    796                         return rc;
    797                
    798                 fibril_mutex_lock(&arp_globals.lock);
    799                 do {
    800                         next = pq_detach(packet);
    801                         rc = arp_receive_message(IPC_GET_DEVICE(*call), packet);
    802                         if (rc != 1) {
    803                                 pq_release_remote(arp_globals.net_phone,
    804                                     packet_get_id(packet));
    805                         }
    806                         packet = next;
    807                 } while (packet);
    808                 fibril_mutex_unlock(&arp_globals.lock);
    809                
    810                 return EOK;
    811        
    812         case NET_IL_MTU_CHANGED:
    813                 return arp_mtu_changed_message(IPC_GET_DEVICE(*call),
    814                     IPC_GET_MTU(*call));
    815860        }
    816861       
     
    818863}
    819864
    820 /** Default thread for new connections.
    821  *
    822  * @param[in] iid   Initial message identifier.
    823  * @param[in] icall Initial message call structure.
    824  */
    825 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    826 {
    827         /*
    828          * Accept the connection
    829          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    830          */
    831         ipc_answer_0(iid, EOK);
    832        
    833         while (true) {
    834                 ipc_call_t answer;
    835                 size_t count;
    836                
    837                 /* Clear the answer structure */
    838                 refresh_answer(&answer, &count);
    839                
    840                 /* Fetch the next message */
    841                 ipc_call_t call;
    842                 ipc_callid_t callid = async_get_call(&call);
    843                
    844                 /* Process the message */
    845                 int res = il_module_message(callid, &call, &answer,
    846                     &count);
    847                
    848                 /*
    849                  * End if told to either by the message or the processing
    850                  * result.
    851                  */
    852                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    853                     (res == EHANGUP))
    854                         return;
    855                
    856                 /* Answer the message */
    857                 answer_call(callid, res, &answer, count);
    858         }
    859 }
    860 
    861865int main(int argc, char *argv[])
    862866{
    863867        /* Start the module */
    864         return il_module_start(il_client_connection);
     868        return il_module_start(SERVICE_ARP);
    865869}
    866870
  • uspace/srv/net/il/arp/arp.h

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

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

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

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

    r73ac2e9 r797b704  
    5757#include <netif_remote.h>
    5858#include <net_interface.h>
    59 #include <il_interface.h>
     59#include <il_remote.h>
    6060#include <adt/measured_strings.h>
    6161#include <packet_client.h>
     
    247247                        rc = packet_translate_remote(eth_globals.net_phone,
    248248                            &packet, IPC_GET_PACKET(*icall));
    249                         if (rc == EOK) {
     249                        if (rc == EOK)
    250250                                rc = nil_received_msg_local(0,
    251251                                    IPC_GET_DEVICE(*icall), packet, 0);
    252                         }
     252                       
    253253                        ipc_answer_0(iid, (sysarg_t) rc);
    254254                        break;
  • uspace/srv/net/nil/nildummy/nildummy.c

    r73ac2e9 r797b704  
    4848#include <net/modules.h>
    4949#include <net/device.h>
    50 #include <il_interface.h>
     50#include <il_remote.h>
    5151#include <adt/measured_strings.h>
    5252#include <net/packet.h>
     
    118118                        rc = packet_translate_remote(nildummy_globals.net_phone,
    119119                            &packet, IPC_GET_PACKET(*icall));
    120                         if (rc == EOK) {
     120                        if (rc == EOK)
    121121                                rc = nil_received_msg_local(0,
    122122                                    IPC_GET_DEVICE(*icall), packet, 0);
    123                         }
     123                       
    124124                        ipc_answer_0(iid, (sysarg_t) rc);
    125125                        break;
  • uspace/srv/net/tl/icmp/icmp.c

    r73ac2e9 r797b704  
    6868#include <icmp_client.h>
    6969#include <icmp_interface.h>
    70 #include <il_interface.h>
     70#include <il_remote.h>
    7171#include <ip_client.h>
    7272#include <ip_interface.h>
Note: See TracChangeset for help on using the changeset viewer.