Changeset eb522e8 in mainline for uspace/srv/net/il/ip/ip.c


Ignore:
Timestamp:
2011-06-01T08:43:42Z (15 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8d6c1f1
Parents:
9e2e715 (diff), e51a514 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Huuuuuge merge from development - all the work actually :)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/il/ip/ip.c

    r9e2e715 reb522e8  
    3636 */
    3737
    38 #include "ip.h"
    39 #include "ip_module.h"
    40 
    4138#include <async.h>
    4239#include <errno.h>
     
    4441#include <stdio.h>
    4542#include <str.h>
    46 #include <ipc/ipc.h>
    4743#include <ipc/services.h>
    4844#include <ipc/net.h>
     
    5248#include <sys/types.h>
    5349#include <byteorder.h>
     50#include "ip.h"
    5451
    5552#include <adt/measured_strings.h>
     
    6966#include <net_checksum.h>
    7067#include <icmp_client.h>
    71 #include <icmp_interface.h>
    72 #include <il_interface.h>
     68#include <icmp_remote.h>
    7369#include <ip_client.h>
    7470#include <ip_interface.h>
    7571#include <ip_header.h>
    7672#include <net_interface.h>
    77 #include <nil_interface.h>
    78 #include <tl_interface.h>
     73#include <nil_remote.h>
     74#include <tl_remote.h>
    7975#include <packet_remote.h>
    80 #include <il_local.h>
     76#include <il_remote.h>
     77#include <il_skel.h>
    8178
    8279/** IP module name. */
     
    123120GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t);
    124121
     122static void ip_receiver(ipc_callid_t, ipc_call_t *);
     123
    125124/** Releases the packet and returns the result.
    126125 *
     
    129128 * @return              The result parameter.
    130129 */
    131 static int ip_release_and_return(packet_t packet, int result)
     130static int ip_release_and_return(packet_t *packet, int result)
    132131{
    133132        pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
     
    139138 * Searches the registered protocols.
    140139 *
    141  * @returns             The found ICMP phone.
    142  * @returns             ENOENT if the ICMP is not registered.
     140 * @return              The found ICMP phone.
     141 * @return              ENOENT if the ICMP is not registered.
    143142 */
    144143static int ip_get_icmp_phone(void)
    145144{
    146         ip_proto_ref proto;
     145        ip_proto_t *proto;
    147146        int phone;
    148147
     
    160159 * @param[in] packet    The packet or the packet queue to be reported as faulty.
    161160 * @param[in] header    The first packet IP header. May be NULL.
    162  * @returns             EOK on success.
    163  * @returns             EINVAL if there are no data in the packet.
    164  * @returns             EINVAL if the packet is a fragment.
    165  * @returns             ENOMEM if the packet is too short to contain the IP
     161 * @return              EOK on success.
     162 * @return              EINVAL if there are no data in the packet.
     163 * @return              EINVAL if the packet is a fragment.
     164 * @return              ENOMEM if the packet is too short to contain the IP
    166165 *                      header.
    167  * @returns             EAFNOSUPPORT if the address family is not supported.
    168  * @returns             EPERM if the protocol is not allowed to send ICMP
     166 * @return              EAFNOSUPPORT if the address family is not supported.
     167 * @return              EPERM if the protocol is not allowed to send ICMP
    169168 *                      notifications. The ICMP protocol itself.
    170  * @returns             Other error codes as defined for the packet_set_addr().
    171  */
    172 static int ip_prepare_icmp(packet_t packet, ip_header_ref header)
    173 {
    174         packet_t next;
     169 * @return              Other error codes as defined for the packet_set_addr().
     170 */
     171static int ip_prepare_icmp(packet_t *packet, ip_header_t *header)
     172{
     173        packet_t *next;
    175174        struct sockaddr *dest;
    176175        struct sockaddr_in dest_in;
    177176        socklen_t addrlen;
    178177
    179         // detach the first packet and release the others
     178        /* Detach the first packet and release the others */
    180179        next = pq_detach(packet);
    181180        if (next)
     
    186185                        return ENOMEM;
    187186
    188                 // get header
    189                 header = (ip_header_ref) packet_get_data(packet);
     187                /* Get header */
     188                header = (ip_header_t *) packet_get_data(packet);
    190189                if (!header)
    191190                        return EINVAL;
     
    193192        }
    194193
    195         // only for the first fragment
     194        /* Only for the first fragment */
    196195        if (IP_FRAGMENT_OFFSET(header))
    197196                return EINVAL;
    198197
    199         // not for the ICMP protocol
     198        /* Not for the ICMP protocol */
    200199        if (header->protocol == IPPROTO_ICMP)
    201200                return EPERM;
    202201
    203         // set the destination address
     202        /* Set the destination address */
    204203        switch (header->version) {
    205204        case IPVERSION:
     
    227226 * @param[in] packet    The packet or the packet queue to be reported as faulty.
    228227 * @param[in] header    The first packet IP header. May be NULL.
    229  * @returns             The found ICMP phone.
    230  * @returns             EINVAL if the error parameter is set.
    231  * @returns             EINVAL if the ICMP phone is not found.
    232  * @returns             EINVAL if the ip_prepare_icmp() fails.
     228 * @return              The found ICMP phone.
     229 * @return              EINVAL if the error parameter is set.
     230 * @return              EINVAL if the ICMP phone is not found.
     231 * @return              EINVAL if the ip_prepare_icmp() fails.
    233232 */
    234233static int
    235 ip_prepare_icmp_and_get_phone(services_t error, packet_t packet,
    236     ip_header_ref header)
     234ip_prepare_icmp_and_get_phone(services_t error, packet_t *packet,
     235    ip_header_t *header)
    237236{
    238237        int phone;
     
    244243}
    245244
    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  * @returns             EOK on success.
    251  * @returns             ENOMEM if there is not enough memory left.
    252  */
    253 int ip_initialize(async_client_conn_t client_connection)
    254 {
    255         int rc;
    256 
     245int il_initialize(int net_phone)
     246{
    257247        fibril_rwlock_initialize(&ip_globals.lock);
    258248        fibril_rwlock_write_lock(&ip_globals.lock);
    259249        fibril_rwlock_initialize(&ip_globals.protos_lock);
    260250        fibril_rwlock_initialize(&ip_globals.netifs_lock);
     251       
     252        ip_globals.net_phone = net_phone;
    261253        ip_globals.packet_counter = 0;
    262254        ip_globals.gateway.address.s_addr = 0;
     
    264256        ip_globals.gateway.gateway.s_addr = 0;
    265257        ip_globals.gateway.netif = NULL;
    266         ip_globals.client_connection = client_connection;
    267        
    268         rc = ip_netifs_initialize(&ip_globals.netifs);
     258       
     259        int rc = ip_netifs_initialize(&ip_globals.netifs);
    269260        if (rc != EOK)
    270261                goto out;
     
    275266        if (rc != EOK)
    276267                goto out;
    277         rc = add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME,
    278             SERVICE_ARP, 0, arp_connect_module);
     268        rc = add_module(NULL, &ip_globals.modules, (uint8_t *) ARP_NAME,
     269            (uint8_t *) ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module);
    279270
    280271out:
     
    293284 *
    294285 * @param[in,out] ip_netif Network interface specific data.
    295  * @returns             EOK on success.
    296  * @returns             ENOTSUP if DHCP is configured.
    297  * @returns             ENOTSUP if IPv6 is configured.
    298  * @returns             EINVAL if any of the addresses is invalid.
    299  * @returns             EINVAL if the used ARP module is not known.
    300  * @returns             ENOMEM if there is not enough memory left.
    301  * @returns             Other error codes as defined for the
     286 * @return              EOK on success.
     287 * @return              ENOTSUP if DHCP is configured.
     288 * @return              ENOTSUP if IPv6 is configured.
     289 * @return              EINVAL if any of the addresses is invalid.
     290 * @return              EINVAL if the used ARP module is not known.
     291 * @return              ENOMEM if there is not enough memory left.
     292 * @return              Other error codes as defined for the
    302293 *                      net_get_device_conf_req() function.
    303  * @returns             Other error codes as defined for the bind_service()
     294 * @return              Other error codes as defined for the bind_service()
    304295 *                      function.
    305  * @returns             Other error codes as defined for the specific
     296 * @return              Other error codes as defined for the specific
    306297 *                      arp_device_req() function.
    307  * @returns             Other error codes as defined for the
     298 * @return              Other error codes as defined for the
    308299 *                      nil_packet_size_req() function.
    309300 */
    310 static int ip_netif_initialize(ip_netif_ref ip_netif)
     301static int ip_netif_initialize(ip_netif_t *ip_netif)
    311302{
    312303        measured_string_t names[] = {
    313304                {
    314                         (char *) "IPV",
     305                        (uint8_t *) "IPV",
    315306                        3
    316307                },
    317308                {
    318                         (char *) "IP_CONFIG",
     309                        (uint8_t *) "IP_CONFIG",
    319310                        9
    320311                },
    321312                {
    322                         (char *) "IP_ADDR",
     313                        (uint8_t *) "IP_ADDR",
    323314                        7
    324315                },
    325316                {
    326                         (char *) "IP_NETMASK",
     317                        (uint8_t *) "IP_NETMASK",
    327318                        10
    328319                },
    329320                {
    330                         (char *) "IP_GATEWAY",
     321                        (uint8_t *) "IP_GATEWAY",
    331322                        10
    332323                },
    333324                {
    334                         (char *) "IP_BROADCAST",
     325                        (uint8_t *) "IP_BROADCAST",
    335326                        12
    336327                },
    337328                {
    338                         (char *) "ARP",
     329                        (uint8_t *) "ARP",
    339330                        3
    340331                },
    341332                {
    342                         (char *) "IP_ROUTING",
     333                        (uint8_t *) "IP_ROUTING",
    343334                        10
    344335                }
    345336        };
    346         measured_string_ref configuration;
     337        measured_string_t *configuration;
    347338        size_t count = sizeof(names) / sizeof(measured_string_t);
    348         char *data;
     339        uint8_t *data;
    349340        measured_string_t address;
    350         ip_route_ref route;
     341        ip_route_t *route;
    351342        in_addr_t gateway;
    352343        int index;
     
    360351        configuration = &names[0];
    361352
    362         // get configuration
     353        /* Get configuration */
    363354        rc = net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id,
    364355            &configuration, count, &data);
     
    368359        if (configuration) {
    369360                if (configuration[0].value)
    370                         ip_netif->ipv = strtol(configuration[0].value, NULL, 0);
    371 
    372                 ip_netif->dhcp = !str_lcmp(configuration[1].value, "dhcp",
     361                        ip_netif->ipv = strtol((char *) configuration[0].value, NULL, 0);
     362               
     363                ip_netif->dhcp = !str_lcmp((char *) configuration[1].value, "dhcp",
    373364                    configuration[1].length);
    374365               
     
    378369                        return ENOTSUP;
    379370                } else if (ip_netif->ipv == IPV4) {
    380                         route = (ip_route_ref) malloc(sizeof(ip_route_t));
     371                        route = (ip_route_t *) malloc(sizeof(ip_route_t));
    381372                        if (!route) {
    382373                                net_free_settings(configuration, data);
     
    394385                        }
    395386                       
    396                         if ((inet_pton(AF_INET, configuration[2].value,
     387                        if ((inet_pton(AF_INET, (char *) configuration[2].value,
    397388                            (uint8_t *) &route->address.s_addr) != EOK) ||
    398                             (inet_pton(AF_INET, configuration[3].value,
     389                            (inet_pton(AF_INET, (char *) configuration[3].value,
    399390                            (uint8_t *) &route->netmask.s_addr) != EOK) ||
    400                             (inet_pton(AF_INET, configuration[4].value,
     391                            (inet_pton(AF_INET, (char *) configuration[4].value,
    401392                            (uint8_t *) &gateway.s_addr) == EINVAL) ||
    402                             (inet_pton(AF_INET, configuration[5].value,
     393                            (inet_pton(AF_INET, (char *) configuration[5].value,
    403394                            (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL))
    404395                            {
     
    428419        }
    429420
    430         // binds the netif service which also initializes the device
     421        /* Bind netif service which also initializes the device */
    431422        ip_netif->phone = nil_bind_service(ip_netif->service,
    432             (ipcarg_t) ip_netif->device_id, SERVICE_IP,
    433             ip_globals.client_connection);
     423            (sysarg_t) ip_netif->device_id, SERVICE_IP,
     424            ip_receiver);
    434425        if (ip_netif->phone < 0) {
    435426                printf("Failed to contact the nil service %d\n",
     
    438429        }
    439430
    440         // has to be after the device netif module initialization
     431        /* Has to be after the device netif module initialization */
    441432        if (ip_netif->arp) {
    442433                if (route) {
    443                         address.value = (char *) &route->address.s_addr;
    444                         address.length = CONVERT_SIZE(in_addr_t, char, 1);
     434                        address.value = (uint8_t *) &route->address.s_addr;
     435                        address.length = sizeof(in_addr_t);
    445436                       
    446437                        rc = arp_device_req(ip_netif->arp->phone,
     
    454445        }
    455446
    456         // get packet dimensions
     447        /* Get packet dimensions */
    457448        rc = nil_packet_size_req(ip_netif->phone, ip_netif->device_id,
    458449            &ip_netif->packet_dimension);
     
    461452       
    462453        if (ip_netif->packet_dimension.content < IP_MIN_CONTENT) {
    463                 printf("Maximum transmission unit %d bytes is too small, at "
     454                printf("Maximum transmission unit %zu bytes is too small, at "
    464455                    "least %d bytes are needed\n",
    465456                    ip_netif->packet_dimension.content, IP_MIN_CONTENT);
     
    472463       
    473464        if (gateway.s_addr) {
    474                 // the default gateway
     465                /* The default gateway */
    475466                ip_globals.gateway.address.s_addr = 0;
    476467                ip_globals.gateway.netmask.s_addr = 0;
    477468                ip_globals.gateway.gateway.s_addr = gateway.s_addr;
    478469                ip_globals.gateway.netif = ip_netif;
     470               
     471                char defgateway[INET_ADDRSTRLEN];
     472                inet_ntop(AF_INET, (uint8_t *) &gateway.s_addr,
     473                    defgateway, INET_ADDRSTRLEN);
     474                printf("%s: Default gateway (%s)\n", NAME, defgateway);
    479475        }
    480476
     
    482478}
    483479
    484 /** Updates the device content length according to the new MTU value.
    485  *
    486  * @param[in] device_id The device identifier.
    487  * @param[in] mtu       The new mtu value.
    488  * @returns             EOK on success.
    489  * @returns             ENOENT if device is not found.
    490  */
    491 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
    492 {
    493         ip_netif_ref netif;
     480static int ip_device_req_local(int il_phone, device_id_t device_id,
     481    services_t netif)
     482{
     483        ip_netif_t *ip_netif;
     484        ip_route_t *route;
     485        int index;
     486        int rc;
     487
     488        ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t));
     489        if (!ip_netif)
     490                return ENOMEM;
     491
     492        rc = ip_routes_initialize(&ip_netif->routes);
     493        if (rc != EOK) {
     494                free(ip_netif);
     495                return rc;
     496        }
     497
     498        ip_netif->device_id = device_id;
     499        ip_netif->service = netif;
     500        ip_netif->state = NETIF_STOPPED;
    494501
    495502        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    496         netif = ip_netifs_find(&ip_globals.netifs, device_id);
    497         if (!netif) {
     503
     504        rc = ip_netif_initialize(ip_netif);
     505        if (rc != EOK) {
    498506                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    499                 return ENOENT;
    500         }
    501         netif->packet_dimension.content = mtu;
     507                ip_routes_destroy(&ip_netif->routes, free);
     508                free(ip_netif);
     509                return rc;
     510        }
     511        if (ip_netif->arp)
     512                ip_netif->arp->usage++;
     513
     514        /* Print the settings */
     515        printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
     516            NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
     517            ip_netif->dhcp ? "dhcp" : "static");
     518       
     519        // TODO ipv6 addresses
     520       
     521        char address[INET_ADDRSTRLEN];
     522        char netmask[INET_ADDRSTRLEN];
     523        char gateway[INET_ADDRSTRLEN];
     524       
     525        for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) {
     526                route = ip_routes_get_index(&ip_netif->routes, index);
     527                if (route) {
     528                        inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr,
     529                            address, INET_ADDRSTRLEN);
     530                        inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr,
     531                            netmask, INET_ADDRSTRLEN);
     532                        inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr,
     533                            gateway, INET_ADDRSTRLEN);
     534                        printf("%s: Route %d (address: %s, netmask: %s, "
     535                            "gateway: %s)\n", NAME, index, address, netmask,
     536                            gateway);
     537                }
     538        }
     539       
     540        inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address,
     541            INET_ADDRSTRLEN);
    502542        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    503543
    504         printf("%s: Device %d changed MTU to %d\n", NAME, device_id, mtu);
     544        printf("%s: Broadcast (%s)\n", NAME, address);
    505545
    506546        return EOK;
    507547}
    508548
    509 /** Updates the device state.
    510  *
    511  * @param[in] device_id The device identifier.
    512  * @param[in] state     The new state value.
    513  * @returns             EOK on success.
    514  * @returns             ENOENT if device is not found.
    515  */
    516 static int ip_device_state_message(device_id_t device_id, device_state_t state)
    517 {
    518         ip_netif_ref netif;
    519 
    520         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    521         // find the device
    522         netif = ip_netifs_find(&ip_globals.netifs, device_id);
    523         if (!netif) {
    524                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    525                 return ENOENT;
    526         }
    527         netif->state = state;
    528         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    529 
    530         printf("%s: Device %d changed state to %d\n", NAME, device_id, state);
    531 
    532         return EOK;
    533 }
    534 
    535 
    536 /** Prefixes a middle fragment header based on the last fragment header to the
    537  * packet.
    538  *
    539  * @param[in] packet    The packet to be prefixed.
    540  * @param[in] last      The last header to be copied.
    541  * @returns             The prefixed middle header.
    542  * @returns             NULL on error.
    543  */
    544 static ip_header_ref
    545 ip_create_middle_header(packet_t packet, ip_header_ref last)
    546 {
    547         ip_header_ref middle;
    548 
    549         middle = (ip_header_ref) packet_suffix(packet, IP_HEADER_LENGTH(last));
    550         if (!middle)
     549/** Searches the network interfaces if there is a suitable route.
     550 *
     551 * @param[in] netif     The network interface to be searched for routes. May be
     552 *                      NULL.
     553 * @param[in] destination The destination address.
     554 * @return              The found route.
     555 * @return              NULL if no route was found.
     556 */
     557static ip_route_t *ip_netif_find_route(ip_netif_t *netif,
     558    in_addr_t destination)
     559{
     560        int index;
     561        ip_route_t *route;
     562       
     563        if (!netif)
    551564                return NULL;
    552         memcpy(middle, last, IP_HEADER_LENGTH(last));
    553         middle->flags |= IPFLAG_MORE_FRAGMENTS;
    554         return middle;
     565       
     566        /* Start with the first one (the direct route) */
     567        for (index = 0; index < ip_routes_count(&netif->routes); index++) {
     568                route = ip_routes_get_index(&netif->routes, index);
     569                if ((route) &&
     570                    ((route->address.s_addr & route->netmask.s_addr) ==
     571                    (destination.s_addr & route->netmask.s_addr)))
     572                        return route;
     573        }
     574
     575        return NULL;
     576}
     577
     578/** Searches all network interfaces if there is a suitable route.
     579 *
     580 * @param[in] destination The destination address.
     581 * @return              The found route.
     582 * @return              NULL if no route was found.
     583 */
     584static ip_route_t *ip_find_route(in_addr_t destination) {
     585        int index;
     586        ip_route_t *route;
     587        ip_netif_t *netif;
     588
     589        /* Start with the last netif - the newest one */
     590        index = ip_netifs_count(&ip_globals.netifs) - 1;
     591        while (index >= 0) {
     592                netif = ip_netifs_get_index(&ip_globals.netifs, index);
     593                if (netif && (netif->state == NETIF_ACTIVE)) {
     594                        route = ip_netif_find_route(netif, destination);
     595                        if (route)
     596                                return route;
     597                }
     598                index--;
     599        }
     600
     601        return &ip_globals.gateway;
     602}
     603
     604/** Returns the network interface's IP address.
     605 *
     606 * @param[in] netif     The network interface.
     607 * @return              The IP address.
     608 * @return              NULL if no IP address was found.
     609 */
     610static in_addr_t *ip_netif_address(ip_netif_t *netif)
     611{
     612        ip_route_t *route;
     613
     614        route = ip_routes_get_index(&netif->routes, 0);
     615        return route ? &route->address : NULL;
    555616}
    556617
     
    562623 * @param[in] first     The original header to be copied.
    563624 */
    564 static void ip_create_last_header(ip_header_ref last, ip_header_ref first)
    565 {
    566         ip_option_ref option;
     625static void ip_create_last_header(ip_header_t *last, ip_header_t *first)
     626{
     627        ip_option_t *option;
    567628        size_t next;
    568629        size_t length;
    569630
    570         // copy first itself
     631        /* Copy first itself */
    571632        memcpy(last, first, sizeof(ip_header_t));
    572633        length = sizeof(ip_header_t);
    573634        next = sizeof(ip_header_t);
    574635
    575         // process all ip options
     636        /* Process all IP options */
    576637        while (next < first->header_length) {
    577                 option = (ip_option_ref) (((uint8_t *) first) + next);
    578                 // skip end or noop
     638                option = (ip_option_t *) (((uint8_t *) first) + next);
     639                /* Skip end or noop */
    579640                if ((option->type == IPOPT_END) ||
    580641                    (option->type == IPOPT_NOOP)) {
    581642                        next++;
    582643                } else {
    583                         // copy if told so or skip
     644                        /* Copy if told so or skip */
    584645                        if (IPOPT_COPIED(option->type)) {
    585646                                memcpy(((uint8_t *) last) + length,
     
    587648                                length += option->length;
    588649                        }
    589                         // next option
     650                        /* Next option */
    590651                        next += option->length;
    591652                }
    592653        }
    593654
    594         // align 4 byte boundary
     655        /* Align 4 byte boundary */
    595656        if (length % 4) {
    596657                bzero(((uint8_t *) last) + length, 4 - (length % 4));
     
    613674 * @param[in,out] packet The packet to be sent.
    614675 * @param[in] destination The destination hardware address.
    615  * @returns             EOK on success.
    616  * @returns             EINVAL if the packet is too small to contain the IP
     676 * @return              EOK on success.
     677 * @return              EINVAL if the packet is too small to contain the IP
    617678 *                      header.
    618  * @returns             EINVAL if the packet is too long than the IP allows.
    619  * @returns             ENOMEM if there is not enough memory left.
    620  * @returns             Other error codes as defined for the packet_set_addr()
     679 * @return              EINVAL if the packet is too long than the IP allows.
     680 * @return              ENOMEM if there is not enough memory left.
     681 * @return              Other error codes as defined for the packet_set_addr()
    621682 *                      function.
    622683 */
    623 static int
    624 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t packet,
    625     measured_string_ref destination)
     684static int ip_prepare_packet(in_addr_t *source, in_addr_t dest,
     685    packet_t *packet, measured_string_t *destination)
    626686{
    627687        size_t length;
    628         ip_header_ref header;
    629         ip_header_ref last_header;
    630         ip_header_ref middle_header;
    631         packet_t next;
     688        ip_header_t *header;
     689        ip_header_t *last_header;
     690        ip_header_t *middle_header;
     691        packet_t *next;
    632692        int rc;
    633693
     
    636696                return EINVAL;
    637697
    638         header = (ip_header_ref) packet_get_data(packet);
     698        header = (ip_header_t *) packet_get_data(packet);
    639699        if (destination) {
    640700                rc = packet_set_addr(packet, NULL, (uint8_t *) destination->value,
    641                     CONVERT_SIZE(char, uint8_t, destination->length));
     701                    destination->length);
    642702        } else {
    643703                rc = packet_set_addr(packet, NULL, NULL, 0);
     
    660720
    661721        if (pq_next(packet)) {
    662                 last_header = (ip_header_ref) malloc(IP_HEADER_LENGTH(header));
     722                last_header = (ip_header_t *) malloc(IP_HEADER_LENGTH(header));
    663723                if (!last_header)
    664724                        return ENOMEM;
     
    666726                next = pq_next(packet);
    667727                while (pq_next(next)) {
    668                         middle_header = (ip_header_ref) packet_prefix(next,
     728                        middle_header = (ip_header_t *) packet_prefix(next,
    669729                            IP_HEADER_LENGTH(last_header));
    670730                        if (!middle_header) {
     
    687747                                rc = packet_set_addr(next, NULL,
    688748                                    (uint8_t *) destination->value,
    689                                     CONVERT_SIZE(char, uint8_t,
    690                                     destination->length));
     749                                    destination->length);
    691750                                if (rc != EOK) {
    692751                                        free(last_header);
     
    698757                }
    699758
    700                 middle_header = (ip_header_ref) packet_prefix(next,
     759                middle_header = (ip_header_t *) packet_prefix(next,
    701760                    IP_HEADER_LENGTH(last_header));
    702761                if (!middle_header) {
     
    718777                        rc = packet_set_addr(next, NULL,
    719778                            (uint8_t *) destination->value,
    720                             CONVERT_SIZE(char, uint8_t, destination->length));
     779                            destination->length);
    721780                        if (rc != EOK) {
    722781                                free(last_header);
     
    730789
    731790        header->total_length = htons(length);
    732         // unnecessary for all protocols
     791        /* Unnecessary for all protocols */
    733792        header->header_checksum = IP_HEADER_CHECKSUM(header);
    734793
     
    746805 * @param[in] dest      The destiantion address.
    747806 * @param[in] addrlen   The address length.
    748  * @returns             EOK on success.
    749  * @returns             ENOMEM if the target packet is too small.
    750  * @returns             Other error codes as defined for the packet_set_addr()
     807 * @return              EOK on success.
     808 * @return              ENOMEM if the target packet is too small.
     809 * @return              Other error codes as defined for the packet_set_addr()
    751810 *                      function.
    752  * @returns             Other error codes as defined for the pq_insert_after()
     811 * @return              Other error codes as defined for the pq_insert_after()
    753812 *                      function.
    754813 */
    755 static int
    756 ip_fragment_packet_data(packet_t packet, packet_t new_packet,
    757     ip_header_ref header, ip_header_ref new_header, size_t length,
     814static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
     815    ip_header_t *header, ip_header_t *new_header, size_t length,
    758816    const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen)
    759817{
     
    790848}
    791849
     850/** Prefixes a middle fragment header based on the last fragment header to the
     851 * packet.
     852 *
     853 * @param[in] packet    The packet to be prefixed.
     854 * @param[in] last      The last header to be copied.
     855 * @return              The prefixed middle header.
     856 * @return              NULL on error.
     857 */
     858static ip_header_t *ip_create_middle_header(packet_t *packet,
     859    ip_header_t *last)
     860{
     861        ip_header_t *middle;
     862
     863        middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));
     864        if (!middle)
     865                return NULL;
     866        memcpy(middle, last, IP_HEADER_LENGTH(last));
     867        middle->flags |= IPFLAG_MORE_FRAGMENTS;
     868        return middle;
     869}
     870
    792871/** Checks the packet length and fragments it if needed.
    793872 *
     
    799878 * @param[in] suffix    The minimum suffix size.
    800879 * @param[in] addr_len  The minimum address length.
    801  * @returns             EOK on success.
    802  * @returns             EINVAL if the packet_get_addr() function fails.
    803  * @returns             EINVAL if the packet does not contain the IP header.
    804  * @returns             EPERM if the packet needs to be fragmented and the
     880 * @return              EOK on success.
     881 * @return              EINVAL if the packet_get_addr() function fails.
     882 * @return              EINVAL if the packet does not contain the IP header.
     883 * @return              EPERM if the packet needs to be fragmented and the
    805884 *                      fragmentation is not allowed.
    806  * @returns             ENOMEM if there is not enough memory left.
    807  * @returns             ENOMEM if there is no packet available.
    808  * @returns             ENOMEM if the packet is too small to contain the IP
     885 * @return              ENOMEM if there is not enough memory left.
     886 * @return              ENOMEM if there is no packet available.
     887 * @return              ENOMEM if the packet is too small to contain the IP
    809888 *                      header.
    810  * @returns             Other error codes as defined for the packet_trim()
     889 * @return              Other error codes as defined for the packet_trim()
    811890 *                      function.
    812  * @returns             Other error codes as defined for the
     891 * @return              Other error codes as defined for the
    813892 *                      ip_create_middle_header() function.
    814  * @returns             Other error codes as defined for the
     893 * @return              Other error codes as defined for the
    815894 *                      ip_fragment_packet_data() function.
    816895 */
    817896static int
    818 ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix,
     897ip_fragment_packet(packet_t *packet, size_t length, size_t prefix, size_t suffix,
    819898    socklen_t addr_len)
    820899{
    821         packet_t new_packet;
    822         ip_header_ref header;
    823         ip_header_ref middle_header;
    824         ip_header_ref last_header;
     900        packet_t *new_packet;
     901        ip_header_t *header;
     902        ip_header_t *middle_header;
     903        ip_header_t *last_header;
    825904        struct sockaddr *src;
    826905        struct sockaddr *dest;
     
    837916                return ENOMEM;
    838917
    839         // get header
    840         header = (ip_header_ref) packet_get_data(packet);
     918        /* Get header */
     919        header = (ip_header_t *) packet_get_data(packet);
    841920        if (!header)
    842921                return EINVAL;
    843922
    844         // fragmentation forbidden?
     923        /* Fragmentation forbidden? */
    845924        if(header->flags & IPFLAG_DONT_FRAGMENT)
    846925                return EPERM;
    847926
    848         // create the last fragment
     927        /* Create the last fragment */
    849928        new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length,
    850929            suffix, ((addrlen > addr_len) ? addrlen : addr_len));
     
    852931                return ENOMEM;
    853932
    854         // allocate as much as originally
    855         last_header = (ip_header_ref) packet_suffix(new_packet,
     933        /* Allocate as much as originally */
     934        last_header = (ip_header_t *) packet_suffix(new_packet,
    856935            IP_HEADER_LENGTH(header));
    857936        if (!last_header)
     
    860939        ip_create_last_header(last_header, header);
    861940
    862         // trim the unused space
     941        /* Trim the unused space */
    863942        rc = packet_trim(new_packet, 0,
    864943            IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header));
     
    866945                return ip_release_and_return(packet, rc);
    867946
    868         // biggest multiple of 8 lower than content
     947        /* Greatest multiple of 8 lower than content */
    869948        // TODO even fragmentation?
    870949        length = length & ~0x7;
     
    878957                return ip_release_and_return(packet, rc);
    879958
    880         // mark the first as fragmented
     959        /* Mark the first as fragmented */
    881960        header->flags |= IPFLAG_MORE_FRAGMENTS;
    882961
    883         // create middle framgents
     962        /* Create middle fragments */
    884963        while (IP_TOTAL_LENGTH(header) > length) {
    885964                new_packet = packet_get_4_remote(ip_globals.net_phone, prefix,
     
    902981        }
    903982
    904         // finish the first fragment
     983        /* Finish the first fragment */
    905984        header->header_checksum = IP_HEADER_CHECKSUM(header);
    906985
     
    919998 * @param[in] addr_len  The minimum address length.
    920999 * @param[in] error     The error module service.
    921  * @returns             The packet or the packet queue of the allowed length.
    922  * @returns             NULL if there are no packets left.
    923  */
    924 static packet_t
    925 ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix,
     1000 * @return              The packet or the packet queue of the allowed length.
     1001 * @return              NULL if there are no packets left.
     1002 */
     1003static packet_t *
     1004ip_split_packet(packet_t *packet, size_t prefix, size_t content, size_t suffix,
    9261005    socklen_t addr_len, services_t error)
    9271006{
    9281007        size_t length;
    929         packet_t next;
    930         packet_t new_packet;
     1008        packet_t *next;
     1009        packet_t *new_packet;
    9311010        int result;
    9321011        int phone;
    9331012
    9341013        next = packet;
    935         // check all packets
     1014        /* Check all packets */
    9361015        while (next) {
    9371016                length = packet_get_data_length(next);
     
    9421021                }
    9431022
    944                 // too long
     1023                /* Too long */
    9451024                result = ip_fragment_packet(next, content, prefix,
    9461025                    suffix, addr_len);
     
    9481027                        new_packet = pq_detach(next);
    9491028                        if (next == packet) {
    950                                 // the new first packet of the queue
     1029                                /* The new first packet of the queue */
    9511030                                packet = new_packet;
    9521031                        }
    953                         // fragmentation needed?
     1032                        /* Fragmentation needed? */
    9541033                        if (result == EPERM) {
    9551034                                phone = ip_prepare_icmp_and_get_phone(
    9561035                                    error, next, NULL);
    9571036                                if (phone >= 0) {
    958                                         // fragmentation necessary ICMP
     1037                                        /* Fragmentation necessary ICMP */
    9591038                                        icmp_destination_unreachable_msg(phone,
    9601039                                            ICMP_FRAG_NEEDED, content, next);
     
    9861065 * @param[in] dest      The destination address.
    9871066 * @param[in] error     The error module service.
    988  * @returns             EOK on success.
    989  * @returns             Other error codes as defined for the arp_translate_req()
     1067 * @return              EOK on success.
     1068 * @return              Other error codes as defined for the arp_translate_req()
    9901069 *                      function.
    991  * @returns             Other error codes as defined for the ip_prepare_packet()
     1070 * @return              Other error codes as defined for the ip_prepare_packet()
    9921071 *                      function.
    9931072 */
    994 static int
    995 ip_send_route(packet_t packet, ip_netif_ref netif, ip_route_ref route,
    996     in_addr_t *src, in_addr_t dest, services_t error)
     1073static int ip_send_route(packet_t *packet, ip_netif_t *netif,
     1074    ip_route_t *route, in_addr_t *src, in_addr_t dest, services_t error)
    9971075{
    9981076        measured_string_t destination;
    999         measured_string_ref translation;
    1000         char *data;
     1077        measured_string_t *translation;
     1078        uint8_t *data;
    10011079        int phone;
    10021080        int rc;
    10031081
    1004         // get destination hardware address
     1082        /* Get destination hardware address */
    10051083        if (netif->arp && (route->address.s_addr != dest.s_addr)) {
    10061084                destination.value = route->gateway.s_addr ?
    1007                     (char *) &route->gateway.s_addr : (char *) &dest.s_addr;
    1008                 destination.length = CONVERT_SIZE(dest.s_addr, char, 1);
     1085                    (uint8_t *) &route->gateway.s_addr : (uint8_t *) &dest.s_addr;
     1086                destination.length = sizeof(dest.s_addr);
    10091087
    10101088                rc = arp_translate_req(netif->arp->phone, netif->device_id,
     
    10241102                            NULL);
    10251103                        if (phone >= 0) {
    1026                                 // unreachable ICMP if no routing
     1104                                /* Unreachable ICMP if no routing */
    10271105                                icmp_destination_unreachable_msg(phone,
    10281106                                    ICMP_HOST_UNREACH, 0, packet);
     
    10571135}
    10581136
    1059 /** Searches the network interfaces if there is a suitable route.
    1060  *
    1061  * @param[in] netif     The network interface to be searched for routes. May be
    1062  *                      NULL.
    1063  * @param[in] destination The destination address.
    1064  * @returns             The found route.
    1065  * @returns             NULL if no route was found.
    1066  */
    1067 static ip_route_ref
    1068 ip_netif_find_route(ip_netif_ref netif, in_addr_t destination)
    1069 {
    1070         int index;
    1071         ip_route_ref route;
    1072 
    1073         if (!netif)
    1074                 return NULL;
    1075 
    1076         // start with the first one - the direct route
    1077         for (index = 0; index < ip_routes_count(&netif->routes); index++) {
    1078                 route = ip_routes_get_index(&netif->routes, index);
    1079                 if (route &&
    1080                     ((route->address.s_addr & route->netmask.s_addr) ==
    1081                     (destination.s_addr & route->netmask.s_addr))) {
    1082                         return route;
    1083                 }
    1084         }
    1085 
    1086         return NULL;
    1087 }
    1088 
    1089 /** Searches all network interfaces if there is a suitable route.
    1090  *
    1091  * @param[in] destination The destination address.
    1092  * @returns             The found route.
    1093  * @returns             NULL if no route was found.
    1094  */
    1095 static ip_route_ref ip_find_route(in_addr_t destination) {
    1096         int index;
    1097         ip_route_ref route;
    1098         ip_netif_ref netif;
    1099 
    1100         // start with the last netif - the newest one
    1101         index = ip_netifs_count(&ip_globals.netifs) - 1;
    1102         while (index >= 0) {
    1103                 netif = ip_netifs_get_index(&ip_globals.netifs, index);
    1104                 if (netif && (netif->state == NETIF_ACTIVE)) {
    1105                         route = ip_netif_find_route(netif, destination);
    1106                         if (route)
    1107                                 return route;
    1108                 }
    1109                 index--;
    1110         }
    1111 
    1112         return &ip_globals.gateway;
    1113 }
    1114 
    1115 /** Returns the network interface's IP address.
    1116  *
    1117  * @param[in] netif     The network interface.
    1118  * @returns             The IP address.
    1119  * @returns             NULL if no IP address was found.
    1120  */
    1121 static in_addr_t *ip_netif_address(ip_netif_ref netif)
    1122 {
    1123         ip_route_ref route;
    1124 
    1125         route = ip_routes_get_index(&netif->routes, 0);
    1126         return route ? &route->address : NULL;
    1127 }
    1128 
    1129 /** Registers the transport layer protocol.
    1130  *
    1131  * The traffic of this protocol will be supplied using either the receive
    1132  * function or IPC message.
    1133  *
    1134  * @param[in] protocol  The transport layer module protocol.
    1135  * @param[in] service   The transport layer module service.
    1136  * @param[in] phone     The transport layer module phone.
    1137  * @param[in] received_msg The receiving function.
    1138  * @returns             EOK on success.
    1139  * @returns             EINVAL if the protocol parameter and/or the service
    1140  *                      parameter is zero.
    1141  * @returns             EINVAL if the phone parameter is not a positive number
    1142  *                      and the tl_receive_msg is NULL.
    1143  * @returns             ENOMEM if there is not enough memory left.
    1144  */
    1145 static int
    1146 ip_register(int protocol, services_t service, int phone,
    1147     tl_received_msg_t received_msg)
    1148 {
    1149         ip_proto_ref proto;
    1150         int index;
    1151 
    1152         if (!protocol || !service || ((phone < 0) && !received_msg))
    1153                 return EINVAL;
    1154 
    1155         proto = (ip_proto_ref) malloc(sizeof(ip_protos_t));
    1156         if (!proto)
    1157                 return ENOMEM;
    1158 
    1159         proto->protocol = protocol;
    1160         proto->service = service;
    1161         proto->phone = phone;
    1162         proto->received_msg = received_msg;
    1163 
    1164         fibril_rwlock_write_lock(&ip_globals.protos_lock);
    1165         index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
    1166         if (index < 0) {
    1167                 fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    1168                 free(proto);
    1169                 return index;
    1170         }
    1171         fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    1172 
    1173         printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
    1174             NAME, proto->protocol, proto->phone);
    1175 
    1176         return EOK;
    1177 }
    1178 
    1179 static int
    1180 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif)
    1181 {
    1182         ip_netif_ref ip_netif;
    1183         ip_route_ref route;
    1184         int index;
    1185         int rc;
    1186 
    1187         ip_netif = (ip_netif_ref) malloc(sizeof(ip_netif_t));
    1188         if (!ip_netif)
    1189                 return ENOMEM;
    1190 
    1191         rc = ip_routes_initialize(&ip_netif->routes);
    1192         if (rc != EOK) {
    1193                 free(ip_netif);
    1194                 return rc;
    1195         }
    1196 
    1197         ip_netif->device_id = device_id;
    1198         ip_netif->service = netif;
    1199         ip_netif->state = NETIF_STOPPED;
    1200 
    1201         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    1202 
    1203         rc = ip_netif_initialize(ip_netif);
    1204         if (rc != EOK) {
    1205                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1206                 ip_routes_destroy(&ip_netif->routes);
    1207                 free(ip_netif);
    1208                 return rc;
    1209         }
    1210         if (ip_netif->arp)
    1211                 ip_netif->arp->usage++;
    1212 
    1213         // print the settings
    1214         printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
    1215             NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
    1216             ip_netif->dhcp ? "dhcp" : "static");
    1217        
    1218         // TODO ipv6 addresses
    1219        
    1220         char address[INET_ADDRSTRLEN];
    1221         char netmask[INET_ADDRSTRLEN];
    1222         char gateway[INET_ADDRSTRLEN];
    1223        
    1224         for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) {
    1225                 route = ip_routes_get_index(&ip_netif->routes, index);
    1226                 if (route) {
    1227                         inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr,
    1228                             address, INET_ADDRSTRLEN);
    1229                         inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr,
    1230                             netmask, INET_ADDRSTRLEN);
    1231                         inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr,
    1232                             gateway, INET_ADDRSTRLEN);
    1233                         printf("%s: Route %d (address: %s, netmask: %s, "
    1234                             "gateway: %s)\n", NAME, index, address, netmask,
    1235                             gateway);
    1236                 }
    1237         }
    1238        
    1239         inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address,
    1240             INET_ADDRSTRLEN);
    1241         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1242 
    1243         printf("%s: Broadcast (%s)\n", NAME, address);
    1244 
    1245         return EOK;
    1246 }
    1247 
    1248 static int
    1249 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t packet,
    1250     services_t sender, services_t error)
     1137static int ip_send_msg_local(int il_phone, device_id_t device_id,
     1138    packet_t *packet, services_t sender, services_t error)
    12511139{
    12521140        int addrlen;
    1253         ip_netif_ref netif;
    1254         ip_route_ref route;
     1141        ip_netif_t *netif;
     1142        ip_route_t *route;
    12551143        struct sockaddr *addr;
    12561144        struct sockaddr_in *address_in;
     
    12601148        int rc;
    12611149
    1262         // addresses in the host byte order
    1263         // should be the next hop address or the target destination address
     1150        /*
     1151         * Addresses in the host byte order
     1152         * Should be the next hop address or the target destination address
     1153         */
    12641154        addrlen = packet_get_addr(packet, NULL, (uint8_t **) &addr);
    12651155        if (addrlen < 0)
     
    12861176        fibril_rwlock_read_lock(&ip_globals.netifs_lock);
    12871177
    1288         // device specified?
     1178        /* Device specified? */
    12891179        if (device_id > 0) {
    12901180                netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1291                 route = ip_netif_find_route(netif, * dest);
     1181                route = ip_netif_find_route(netif, *dest);
    12921182                if (netif && !route && (ip_globals.gateway.netif == netif))
    12931183                        route = &ip_globals.gateway;
     
    13021192                phone = ip_prepare_icmp_and_get_phone(error, packet, NULL);
    13031193                if (phone >= 0) {
    1304                         // unreachable ICMP if no routing
     1194                        /* Unreachable ICMP if no routing */
    13051195                        icmp_destination_unreachable_msg(phone,
    13061196                            ICMP_NET_UNREACH, 0, packet);
     
    13101200
    13111201        if (error) {
    1312                 // do not send for broadcast, anycast packets or network
    1313                 // broadcast
     1202                /*
     1203                 * Do not send for broadcast, anycast packets or network
     1204                 * broadcast.
     1205                 */
    13141206                if (!dest->s_addr || !(~dest->s_addr) ||
    13151207                    !(~((dest->s_addr & ~route->netmask.s_addr) |
     
    13191211                }
    13201212        }
    1321 
    1322         // if the local host is the destination
     1213       
     1214        /* If the local host is the destination */
    13231215        if ((route->address.s_addr == dest->s_addr) &&
    13241216            (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) {
    1325                 // find the loopback device to deliver
     1217                /* Find the loopback device to deliver */
    13261218                dest->s_addr = IPV4_LOCALHOST_ADDRESS;
    13271219                route = ip_find_route(*dest);
     
    13321224                            NULL);
    13331225                        if (phone >= 0) {
    1334                                 // unreachable ICMP if no routing
     1226                                /* Unreachable ICMP if no routing */
    13351227                                icmp_destination_unreachable_msg(phone,
    13361228                                    ICMP_HOST_UNREACH, 0, packet);
     
    13501242
    13511243        return rc;
     1244}
     1245
     1246/** Updates the device state.
     1247 *
     1248 * @param[in] device_id The device identifier.
     1249 * @param[in] state     The new state value.
     1250 * @return              EOK on success.
     1251 * @return              ENOENT if device is not found.
     1252 */
     1253static int ip_device_state_message(device_id_t device_id, device_state_t state)
     1254{
     1255        ip_netif_t *netif;
     1256
     1257        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     1258        /* Find the device */
     1259        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1260        if (!netif) {
     1261                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1262                return ENOENT;
     1263        }
     1264        netif->state = state;
     1265        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1266
     1267        printf("%s: Device %d changed state to %d\n", NAME, device_id, state);
     1268
     1269        return EOK;
     1270}
     1271
     1272/** Returns the packet destination address from the IP header.
     1273 *
     1274 * @param[in] header    The packet IP header to be read.
     1275 * @return              The packet destination address.
     1276 */
     1277static in_addr_t ip_get_destination(ip_header_t *header)
     1278{
     1279        in_addr_t destination;
     1280
     1281        // TODO search set ipopt route?
     1282        destination.s_addr = header->destination_address;
     1283        return destination;
     1284}
     1285
     1286/** Delivers the packet to the local host.
     1287 *
     1288 * The packet is either passed to another module or released on error.
     1289 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not
     1290 * found.
     1291 *
     1292 * @param[in] device_id The source device identifier.
     1293 * @param[in] packet    The packet to be delivered.
     1294 * @param[in] header    The first packet IP header. May be NULL.
     1295 * @param[in] error     The packet error service.
     1296 * @return              EOK on success.
     1297 * @return              ENOTSUP if the packet is a fragment.
     1298 * @return              EAFNOSUPPORT if the address family is not supported.
     1299 * @return              ENOENT if the target protocol is not found.
     1300 * @return              Other error codes as defined for the packet_set_addr()
     1301 *                      function.
     1302 * @return              Other error codes as defined for the packet_trim()
     1303 *                      function.
     1304 * @return              Other error codes as defined for the protocol specific
     1305 *                      tl_received_msg() function.
     1306 */
     1307static int ip_deliver_local(device_id_t device_id, packet_t *packet,
     1308    ip_header_t *header, services_t error)
     1309{
     1310        ip_proto_t *proto;
     1311        int phone;
     1312        services_t service;
     1313        tl_received_msg_t received_msg;
     1314        struct sockaddr *src;
     1315        struct sockaddr *dest;
     1316        struct sockaddr_in src_in;
     1317        struct sockaddr_in dest_in;
     1318        socklen_t addrlen;
     1319        int rc;
     1320
     1321        if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
     1322            IP_FRAGMENT_OFFSET(header)) {
     1323                // TODO fragmented
     1324                return ENOTSUP;
     1325        }
     1326       
     1327        switch (header->version) {
     1328        case IPVERSION:
     1329                addrlen = sizeof(src_in);
     1330                bzero(&src_in, addrlen);
     1331                src_in.sin_family = AF_INET;
     1332                memcpy(&dest_in, &src_in, addrlen);
     1333                memcpy(&src_in.sin_addr.s_addr, &header->source_address,
     1334                    sizeof(header->source_address));
     1335                memcpy(&dest_in.sin_addr.s_addr, &header->destination_address,
     1336                    sizeof(header->destination_address));
     1337                src = (struct sockaddr *) &src_in;
     1338                dest = (struct sockaddr *) &dest_in;
     1339                break;
     1340
     1341        default:
     1342                return ip_release_and_return(packet, EAFNOSUPPORT);
     1343        }
     1344
     1345        rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest,
     1346            addrlen);
     1347        if (rc != EOK)
     1348                return ip_release_and_return(packet, rc);
     1349
     1350        /* Trim padding if present */
     1351        if (!error &&
     1352            (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) {
     1353                rc = packet_trim(packet, 0,
     1354                    packet_get_data_length(packet) - IP_TOTAL_LENGTH(header));
     1355                if (rc != EOK)
     1356                        return ip_release_and_return(packet, rc);
     1357        }
     1358
     1359        fibril_rwlock_read_lock(&ip_globals.protos_lock);
     1360
     1361        proto = ip_protos_find(&ip_globals.protos, header->protocol);
     1362        if (!proto) {
     1363                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1364                phone = ip_prepare_icmp_and_get_phone(error, packet, header);
     1365                if (phone >= 0) {
     1366                        /* Unreachable ICMP */
     1367                        icmp_destination_unreachable_msg(phone,
     1368                            ICMP_PROT_UNREACH, 0, packet);
     1369                }
     1370                return ENOENT;
     1371        }
     1372
     1373        if (proto->received_msg) {
     1374                service = proto->service;
     1375                received_msg = proto->received_msg;
     1376                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1377                rc = received_msg(device_id, packet, service, error);
     1378        } else {
     1379                rc = tl_received_msg(proto->phone, device_id, packet,
     1380                    proto->service, error);
     1381                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1382        }
     1383
     1384        return rc;
     1385}
     1386
     1387/** Processes the received packet.
     1388 *
     1389 * The packet is either passed to another module or released on error.
     1390 *
     1391 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is
     1392 * invalid.
     1393 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two.
     1394 * The ICMP_HOST_UNREACH error notification may be sent if no route was found.
     1395 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for
     1396 * another host and the routing is disabled.
     1397 *
     1398 * @param[in] device_id The source device identifier.
     1399 * @param[in] packet    The received packet to be processed.
     1400 * @return              EOK on success.
     1401 * @return              EINVAL if the TTL is less than two.
     1402 * @return              EINVAL if the checksum is invalid.
     1403 * @return              EAFNOSUPPORT if the address family is not supported.
     1404 * @return              ENOENT if no route was found.
     1405 * @return              ENOENT if the packet is for another host and the routing
     1406 *                      is disabled.
     1407 */
     1408static int ip_process_packet(device_id_t device_id, packet_t *packet)
     1409{
     1410        ip_header_t *header;
     1411        in_addr_t dest;
     1412        ip_route_t *route;
     1413        int phone;
     1414        struct sockaddr *addr;
     1415        struct sockaddr_in addr_in;
     1416        socklen_t addrlen;
     1417        int rc;
     1418       
     1419        header = (ip_header_t *) packet_get_data(packet);
     1420        if (!header)
     1421                return ip_release_and_return(packet, ENOMEM);
     1422
     1423        /* Checksum */
     1424        if ((header->header_checksum) &&
     1425            (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
     1426                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1427                if (phone >= 0) {
     1428                        /* Checksum error ICMP */
     1429                        icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
     1430                            ((size_t) ((void *) &header->header_checksum)) -
     1431                            ((size_t) ((void *) header)), packet);
     1432                }
     1433                return EINVAL;
     1434        }
     1435
     1436        if (header->ttl <= 1) {
     1437                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1438                if (phone >= 0) {
     1439                        /* TTL exceeded ICMP */
     1440                        icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
     1441                }
     1442                return EINVAL;
     1443        }
     1444       
     1445        /* Process ipopt and get destination */
     1446        dest = ip_get_destination(header);
     1447
     1448        /* Set the destination address */
     1449        switch (header->version) {
     1450        case IPVERSION:
     1451                addrlen = sizeof(addr_in);
     1452                bzero(&addr_in, addrlen);
     1453                addr_in.sin_family = AF_INET;
     1454                memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest));
     1455                addr = (struct sockaddr *) &addr_in;
     1456                break;
     1457
     1458        default:
     1459                return ip_release_and_return(packet, EAFNOSUPPORT);
     1460        }
     1461
     1462        rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen);
     1463        if (rc != EOK)
     1464                return rc;
     1465       
     1466        route = ip_find_route(dest);
     1467        if (!route) {
     1468                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1469                if (phone >= 0) {
     1470                        /* Unreachable ICMP */
     1471                        icmp_destination_unreachable_msg(phone,
     1472                            ICMP_HOST_UNREACH, 0, packet);
     1473                }
     1474                return ENOENT;
     1475        }
     1476
     1477        if (route->address.s_addr == dest.s_addr) {
     1478                /* Local delivery */
     1479                return ip_deliver_local(device_id, packet, header, 0);
     1480        }
     1481
     1482        if (route->netif->routing) {
     1483                header->ttl--;
     1484                return ip_send_route(packet, route->netif, route, NULL, dest,
     1485                    0);
     1486        }
     1487
     1488        phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1489        if (phone >= 0) {
     1490                /* Unreachable ICMP if no routing */
     1491                icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
     1492                    packet);
     1493        }
     1494       
     1495        return ENOENT;
    13521496}
    13531497
     
    13611505 * @param[out] content  The maximum content size.
    13621506 * @param[out] suffix   The minimum reserved suffix size.
    1363  * @returns             EOK on success.
    1364  */
    1365 static int
    1366 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix,
    1367     size_t *content, size_t *suffix)
    1368 {
    1369         ip_netif_ref netif;
     1507 * @return              EOK on success.
     1508 */
     1509static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,
     1510    size_t *prefix, size_t *content, size_t *suffix)
     1511{
     1512        ip_netif_t *netif;
    13701513        int index;
    13711514
     
    14151558}
    14161559
    1417 /** Returns the packet destination address from the IP header.
    1418  *
    1419  * @param[in] header    The packet IP header to be read.
    1420  * @returns             The packet destination address.
    1421  */
    1422 static in_addr_t ip_get_destination(ip_header_ref header)
    1423 {
    1424         in_addr_t destination;
    1425 
    1426         // TODO search set ipopt route?
    1427         destination.s_addr = header->destination_address;
    1428         return destination;
    1429 }
    1430 
    1431 /** Delivers the packet to the local host.
    1432  *
    1433  * The packet is either passed to another module or released on error.
    1434  * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not
    1435  * found.
    1436  *
    1437  * @param[in] device_id The source device identifier.
    1438  * @param[in] packet    The packet to be delivered.
    1439  * @param[in] header    The first packet IP header. May be NULL.
    1440  * @param[in] error     The packet error service.
    1441  * @returns             EOK on success.
    1442  * @returns             ENOTSUP if the packet is a fragment.
    1443  * @returns             EAFNOSUPPORT if the address family is not supported.
    1444  * @returns             ENOENT if the target protocol is not found.
    1445  * @returns             Other error codes as defined for the packet_set_addr()
    1446  *                      function.
    1447  * @returns             Other error codes as defined for the packet_trim()
    1448  *                      function.
    1449  * @returns             Other error codes as defined for the protocol specific
    1450  *                      tl_received_msg() function.
    1451  */
    1452 static int
    1453 ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header,
    1454     services_t error)
    1455 {
    1456         ip_proto_ref proto;
    1457         int phone;
    1458         services_t service;
    1459         tl_received_msg_t received_msg;
    1460         struct sockaddr *src;
    1461         struct sockaddr *dest;
    1462         struct sockaddr_in src_in;
    1463         struct sockaddr_in dest_in;
    1464         socklen_t addrlen;
    1465         int rc;
    1466 
    1467         if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
    1468             IP_FRAGMENT_OFFSET(header)) {
    1469                 // TODO fragmented
    1470                 return ENOTSUP;
    1471         }
    1472        
    1473         switch (header->version) {
    1474         case IPVERSION:
    1475                 addrlen = sizeof(src_in);
    1476                 bzero(&src_in, addrlen);
    1477                 src_in.sin_family = AF_INET;
    1478                 memcpy(&dest_in, &src_in, addrlen);
    1479                 memcpy(&src_in.sin_addr.s_addr, &header->source_address,
    1480                     sizeof(header->source_address));
    1481                 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address,
    1482                     sizeof(header->destination_address));
    1483                 src = (struct sockaddr *) &src_in;
    1484                 dest = (struct sockaddr *) &dest_in;
    1485                 break;
    1486 
    1487         default:
    1488                 return ip_release_and_return(packet, EAFNOSUPPORT);
    1489         }
    1490 
    1491         rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest,
    1492             addrlen);
    1493         if (rc != EOK)
    1494                 return ip_release_and_return(packet, rc);
    1495 
    1496         // trim padding if present
    1497         if (!error &&
    1498             (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) {
    1499                 rc = packet_trim(packet, 0,
    1500                     packet_get_data_length(packet) - IP_TOTAL_LENGTH(header));
    1501                 if (rc != EOK)
    1502                         return ip_release_and_return(packet, rc);
    1503         }
    1504 
    1505         fibril_rwlock_read_lock(&ip_globals.protos_lock);
    1506 
    1507         proto = ip_protos_find(&ip_globals.protos, header->protocol);
    1508         if (!proto) {
    1509                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1510                 phone = ip_prepare_icmp_and_get_phone(error, packet, header);
    1511                 if (phone >= 0) {
    1512                         // unreachable ICMP
    1513                         icmp_destination_unreachable_msg(phone,
    1514                             ICMP_PROT_UNREACH, 0, packet);
    1515                 }
    1516                 return ENOENT;
    1517         }
    1518 
    1519         if (proto->received_msg) {
    1520                 service = proto->service;
    1521                 received_msg = proto->received_msg;
    1522                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1523                 rc = received_msg(device_id, packet, service, error);
    1524         } else {
    1525                 rc = tl_received_msg(proto->phone, device_id, packet,
    1526                     proto->service, error);
    1527                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1528         }
    1529 
    1530         return rc;
    1531 }
    1532 
    1533 /** Processes the received packet.
    1534  *
    1535  * The packet is either passed to another module or released on error.
    1536  *
    1537  * The ICMP_PARAM_POINTER error notification may be sent if the checksum is
    1538  * invalid.
    1539  * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two.
    1540  * The ICMP_HOST_UNREACH error notification may be sent if no route was found.
    1541  * The ICMP_HOST_UNREACH error notification may be sent if the packet is for
    1542  * another host and the routing is disabled.
    1543  *
    1544  * @param[in] device_id The source device identifier.
    1545  * @param[in] packet    The received packet to be processed.
    1546  * @returns             EOK on success.
    1547  * @returns             EINVAL if the TTL is less than two.
    1548  * @returns             EINVAL if the checksum is invalid.
    1549  * @returns             EAFNOSUPPORT if the address family is not supported.
    1550  * @returns             ENOENT if no route was found.
    1551  * @returns             ENOENT if the packet is for another host and the routing
    1552  *                      is disabled.
    1553  */
    1554 static int
    1555 ip_process_packet(device_id_t device_id, packet_t packet)
    1556 {
    1557         ip_header_ref header;
    1558         in_addr_t dest;
    1559         ip_route_ref route;
    1560         int phone;
    1561         struct sockaddr *addr;
    1562         struct sockaddr_in addr_in;
    1563         socklen_t addrlen;
    1564         int rc;
    1565 
    1566         header = (ip_header_ref) packet_get_data(packet);
    1567         if (!header)
    1568                 return ip_release_and_return(packet, ENOMEM);
    1569 
    1570         // checksum
    1571         if ((header->header_checksum) &&
    1572             (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
    1573                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1574                 if (phone >= 0) {
    1575                         // checksum error ICMP
    1576                         icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
    1577                             ((size_t) ((void *) &header->header_checksum)) -
    1578                             ((size_t) ((void *) header)), packet);
    1579                 }
    1580                 return EINVAL;
    1581         }
    1582 
    1583         if (header->ttl <= 1) {
    1584                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1585                 if (phone >= 0) {
    1586                         // ttl exceeded ICMP
    1587                         icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
    1588                 }
    1589                 return EINVAL;
    1590         }
    1591 
    1592         // process ipopt and get destination
    1593         dest = ip_get_destination(header);
    1594 
    1595         // set the addrination address
    1596         switch (header->version) {
    1597         case IPVERSION:
    1598                 addrlen = sizeof(addr_in);
    1599                 bzero(&addr_in, addrlen);
    1600                 addr_in.sin_family = AF_INET;
    1601                 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest));
    1602                 addr = (struct sockaddr *) &addr_in;
    1603                 break;
    1604 
    1605         default:
    1606                 return ip_release_and_return(packet, EAFNOSUPPORT);
    1607         }
    1608 
    1609         rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen);
    1610         if (rc != EOK)
    1611                 return rc;
    1612 
    1613         route = ip_find_route(dest);
    1614         if (!route) {
    1615                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1616                 if (phone >= 0) {
    1617                         // unreachable ICMP
    1618                         icmp_destination_unreachable_msg(phone,
    1619                             ICMP_HOST_UNREACH, 0, packet);
    1620                 }
    1621                 return ENOENT;
    1622         }
    1623 
    1624         if (route->address.s_addr == dest.s_addr) {
    1625                 // local delivery
    1626                 return ip_deliver_local(device_id, packet, header, 0);
    1627         }
    1628 
    1629         if (route->netif->routing) {
    1630                 header->ttl--;
    1631                 return ip_send_route(packet, route->netif, route, NULL, dest,
    1632                     0);
    1633         }
    1634 
    1635         phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1636         if (phone >= 0) {
    1637                 // unreachable ICMP if no routing
    1638                 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
    1639                     packet);
    1640         }
    1641        
    1642         return ENOENT;
    1643 }
    1644 
    1645 static int
    1646 ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address,
    1647     in_addr_t netmask, in_addr_t gateway)
    1648 {
    1649         ip_route_ref route;
    1650         ip_netif_ref netif;
    1651         int index;
     1560/** Updates the device content length according to the new MTU value.
     1561 *
     1562 * @param[in] device_id The device identifier.
     1563 * @param[in] mtu       The new mtu value.
     1564 * @return              EOK on success.
     1565 * @return              ENOENT if device is not found.
     1566 */
     1567static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
     1568{
     1569        ip_netif_t *netif;
    16521570
    16531571        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    1654 
    16551572        netif = ip_netifs_find(&ip_globals.netifs, device_id);
    16561573        if (!netif) {
     
    16581575                return ENOENT;
    16591576        }
    1660 
    1661         route = (ip_route_ref) malloc(sizeof(ip_route_t));
     1577        netif->packet_dimension.content = mtu;
     1578        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1579
     1580        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
     1581
     1582        return EOK;
     1583}
     1584
     1585/** Process IPC messages from the registered device driver modules
     1586 *
     1587 * @param[in]     iid   Message identifier.
     1588 * @param[in,out] icall Message parameters.
     1589 *
     1590 */
     1591static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall)
     1592{
     1593        packet_t *packet;
     1594        int rc;
     1595       
     1596        while (true) {
     1597                switch (IPC_GET_IMETHOD(*icall)) {
     1598                case NET_IL_DEVICE_STATE:
     1599                        rc = ip_device_state_message(IPC_GET_DEVICE(*icall),
     1600                            IPC_GET_STATE(*icall));
     1601                        async_answer_0(iid, (sysarg_t) rc);
     1602                        break;
     1603               
     1604                case NET_IL_RECEIVED:
     1605                        rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1606                            IPC_GET_PACKET(*icall));
     1607                        if (rc == EOK) {
     1608                                do {
     1609                                        packet_t *next = pq_detach(packet);
     1610                                        ip_process_packet(IPC_GET_DEVICE(*icall), packet);
     1611                                        packet = next;
     1612                                } while (packet);
     1613                        }
     1614                       
     1615                        async_answer_0(iid, (sysarg_t) rc);
     1616                        break;
     1617               
     1618                case NET_IL_MTU_CHANGED:
     1619                        rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall),
     1620                            IPC_GET_MTU(*icall));
     1621                        async_answer_0(iid, (sysarg_t) rc);
     1622                        break;
     1623               
     1624                default:
     1625                        async_answer_0(iid, (sysarg_t) ENOTSUP);
     1626                }
     1627               
     1628                iid = async_get_call(icall);
     1629        }
     1630}
     1631
     1632/** Registers the transport layer protocol.
     1633 *
     1634 * The traffic of this protocol will be supplied using either the receive
     1635 * function or IPC message.
     1636 *
     1637 * @param[in] protocol  The transport layer module protocol.
     1638 * @param[in] service   The transport layer module service.
     1639 * @param[in] phone     The transport layer module phone.
     1640 * @param[in] received_msg The receiving function.
     1641 * @return              EOK on success.
     1642 * @return              EINVAL if the protocol parameter and/or the service
     1643 *                      parameter is zero.
     1644 * @return              EINVAL if the phone parameter is not a positive number
     1645 *                      and the tl_receive_msg is NULL.
     1646 * @return              ENOMEM if there is not enough memory left.
     1647 */
     1648static int
     1649ip_register(int protocol, services_t service, int phone,
     1650    tl_received_msg_t received_msg)
     1651{
     1652        ip_proto_t *proto;
     1653        int index;
     1654
     1655        if (!protocol || !service || ((phone < 0) && !received_msg))
     1656                return EINVAL;
     1657
     1658        proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
     1659        if (!proto)
     1660                return ENOMEM;
     1661
     1662        proto->protocol = protocol;
     1663        proto->service = service;
     1664        proto->phone = phone;
     1665        proto->received_msg = received_msg;
     1666
     1667        fibril_rwlock_write_lock(&ip_globals.protos_lock);
     1668        index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
     1669        if (index < 0) {
     1670                fibril_rwlock_write_unlock(&ip_globals.protos_lock);
     1671                free(proto);
     1672                return index;
     1673        }
     1674        fibril_rwlock_write_unlock(&ip_globals.protos_lock);
     1675
     1676        printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
     1677            NAME, proto->protocol, proto->phone);
     1678
     1679        return EOK;
     1680}
     1681
     1682
     1683static int
     1684ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address,
     1685    in_addr_t netmask, in_addr_t gateway)
     1686{
     1687        ip_route_t *route;
     1688        ip_netif_t *netif;
     1689        int index;
     1690
     1691        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     1692
     1693        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1694        if (!netif) {
     1695                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1696                return ENOENT;
     1697        }
     1698
     1699        route = (ip_route_t *) malloc(sizeof(ip_route_t));
    16621700        if (!route) {
    16631701                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     
    16811719ip_set_gateway_req_local(int ip_phone, device_id_t device_id, in_addr_t gateway)
    16821720{
    1683         ip_netif_ref netif;
     1721        ip_netif_t *netif;
    16841722
    16851723        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     
    17151753static int
    17161754ip_received_error_msg_local(int ip_phone, device_id_t device_id,
    1717     packet_t packet, services_t target, services_t error)
     1755    packet_t *packet, services_t target, services_t error)
    17181756{
    17191757        uint8_t *data;
     
    17211759        icmp_type_t type;
    17221760        icmp_code_t code;
    1723         ip_netif_ref netif;
     1761        ip_netif_t *netif;
    17241762        measured_string_t address;
    1725         ip_route_ref route;
    1726         ip_header_ref header;
     1763        ip_route_t *route;
     1764        ip_header_t *header;
    17271765
    17281766        switch (error) {
     
    17341772
    17351773                data = packet_get_data(packet);
    1736                 header = (ip_header_ref)(data + offset);
    1737 
    1738                 // destination host unreachable?
     1774                header = (ip_header_t *)(data + offset);
     1775
     1776                /* Destination host unreachable? */
    17391777                if ((type != ICMP_DEST_UNREACH) ||
    17401778                    (code != ICMP_HOST_UNREACH)) {
    1741                         // no, something else
     1779                        /* No, something else */
    17421780                        break;
    17431781                }
     
    17531791                route = ip_routes_get_index(&netif->routes, 0);
    17541792
    1755                 // from the same network?
     1793                /* From the same network? */
    17561794                if (route && ((route->address.s_addr & route->netmask.s_addr) ==
    17571795                    (header->destination_address & route->netmask.s_addr))) {
    1758                         // clear the ARP mapping if any
    1759                         address.value = (char *) &header->destination_address;
    1760                         address.length = CONVERT_SIZE(uint8_t, char,
    1761                             sizeof(header->destination_address));
     1796                        /* Clear the ARP mapping if any */
     1797                        address.value = (uint8_t *) &header->destination_address;
     1798                        address.length = sizeof(header->destination_address);
    17621799                        arp_clear_address_req(netif->arp->phone,
    17631800                            netif->device_id, SERVICE_IP, &address);
     
    17821819        in_addr_t *dest;
    17831820        in_addr_t *src;
    1784         ip_route_ref route;
    1785         ipv4_pseudo_header_ref header_in;
     1821        ip_route_t *route;
     1822        ipv4_pseudo_header_t *header_in;
    17861823
    17871824        if (!destination || (addrlen <= 0))
     
    18111848        fibril_rwlock_read_lock(&ip_globals.lock);
    18121849        route = ip_find_route(*dest);
    1813         // if the local host is the destination
     1850        /* If the local host is the destination */
    18141851        if (route && (route->address.s_addr == dest->s_addr) &&
    18151852            (dest->s_addr != IPV4_LOCALHOST_ADDRESS)) {
    1816                 // find the loopback device to deliver
     1853                /* Find the loopback device to deliver */
    18171854                dest->s_addr = IPV4_LOCALHOST_ADDRESS;
    18181855                route = ip_find_route(*dest);
     
    18291866
    18301867        *headerlen = sizeof(*header_in);
    1831         header_in = (ipv4_pseudo_header_ref) malloc(*headerlen);
     1868        header_in = (ipv4_pseudo_header_t *) malloc(*headerlen);
    18321869        if (!header_in)
    18331870                return ENOMEM;
     
    18431880}
    18441881
    1845 /** Processes the received IP packet or the packet queue one by one.
    1846  *
    1847  * The packet is either passed to another module or released on error.
    1848  *
    1849  * @param[in] device_id The source device identifier.
    1850  * @param[in,out] packet The received packet.
    1851  * @returns             EOK on success and the packet is no longer needed.
    1852  * @returns             EINVAL if the packet is too small to carry the IP
    1853  *                      packet.
    1854  * @returns             EINVAL if the received address lengths differs from the
    1855  *                      registered values.
    1856  * @returns             ENOENT if the device is not found in the cache.
    1857  * @returns             ENOENT if the protocol for the device is not found in
    1858  *                      the cache.
    1859  * @returns             ENOMEM if there is not enough memory left.
    1860  */
    1861 static int ip_receive_message(device_id_t device_id, packet_t packet)
    1862 {
    1863         packet_t next;
    1864 
    1865         do {
    1866                 next = pq_detach(packet);
    1867                 ip_process_packet(device_id, packet);
    1868                 packet = next;
    1869         } while (packet);
    1870 
    1871         return EOK;
    1872 }
    1873 
    18741882/** Processes the IP message.
    18751883 *
     
    18791887 * @param[out] answer_count The last parameter for the actual answer in the
    18801888 *                      answer parameter.
    1881  * @returns             EOK on success.
    1882  * @returns             ENOTSUP if the message is not known.
     1889 * @return              EOK on success.
     1890 * @return              ENOTSUP if the message is not known.
    18831891 *
    18841892 * @see ip_interface.h
    1885  * @see il_interface.h
     1893 * @see il_remote.h
    18861894 * @see IS_NET_IP_MESSAGE()
    18871895 */
    1888 int
    1889 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    1890     int *answer_count)
    1891 {
    1892         packet_t packet;
     1896int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     1897    size_t *answer_count)
     1898{
     1899        packet_t *packet;
    18931900        struct sockaddr *addr;
     1901        void *header;
     1902        size_t headerlen;
    18941903        size_t addrlen;
    18951904        size_t prefix;
    18961905        size_t suffix;
    18971906        size_t content;
    1898         void *header;
    1899         size_t headerlen;
    19001907        device_id_t device_id;
    19011908        int rc;
    19021909       
    19031910        *answer_count = 0;
    1904         switch (IPC_GET_METHOD(*call)) {
     1911        switch (IPC_GET_IMETHOD(*call)) {
    19051912        case IPC_M_PHONE_HUNGUP:
    19061913                return EOK;
    19071914       
    19081915        case IPC_M_CONNECT_TO_ME:
    1909                 return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call),
    1910                     IPC_GET_PHONE(call), NULL);
    1911        
    1912         case NET_IL_DEVICE:
    1913                 return ip_device_req_local(0, IPC_GET_DEVICE(call),
    1914                     IPC_GET_SERVICE(call));
    1915        
    1916         case NET_IL_SEND:
     1916                return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
     1917                    IPC_GET_PHONE(*call), NULL);
     1918       
     1919        case NET_IP_DEVICE:
     1920                return ip_device_req_local(0, IPC_GET_DEVICE(*call),
     1921                    IPC_GET_SERVICE(*call));
     1922       
     1923        case NET_IP_RECEIVED_ERROR:
    19171924                rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1918                     IPC_GET_PACKET(call));
     1925                    IPC_GET_PACKET(*call));
    19191926                if (rc != EOK)
    19201927                        return rc;
    1921                 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0,
    1922                     IPC_GET_ERROR(call));
    1923        
    1924         case NET_IL_DEVICE_STATE:
    1925                 return ip_device_state_message(IPC_GET_DEVICE(call),
    1926                     IPC_GET_STATE(call));
    1927        
    1928         case NET_IL_RECEIVED:
    1929                 rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1930                     IPC_GET_PACKET(call));
    1931                 if (rc != EOK)
    1932                         return rc;
    1933                 return ip_receive_message(IPC_GET_DEVICE(call), packet);
    1934        
    1935         case NET_IP_RECEIVED_ERROR:
    1936                 rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1937                     IPC_GET_PACKET(call));
    1938                 if (rc != EOK)
    1939                         return rc;
    1940                 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call),
    1941                     packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));
     1928                return ip_received_error_msg_local(0, IPC_GET_DEVICE(*call),
     1929                    packet, IPC_GET_TARGET(*call), IPC_GET_ERROR(*call));
    19421930       
    19431931        case NET_IP_ADD_ROUTE:
    1944                 return ip_add_route_req_local(0, IPC_GET_DEVICE(call),
    1945                     IP_GET_ADDRESS(call), IP_GET_NETMASK(call),
    1946                     IP_GET_GATEWAY(call));
     1932                return ip_add_route_req_local(0, IPC_GET_DEVICE(*call),
     1933                    IP_GET_ADDRESS(*call), IP_GET_NETMASK(*call),
     1934                    IP_GET_GATEWAY(*call));
    19471935
    19481936        case NET_IP_SET_GATEWAY:
    1949                 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(call),
    1950                     IP_GET_GATEWAY(call));
     1937                return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call),
     1938                    IP_GET_GATEWAY(*call));
    19511939
    19521940        case NET_IP_GET_ROUTE:
    1953                 rc = data_receive((void **) &addr, &addrlen);
     1941                rc = async_data_write_accept((void **) &addr, false, 0, 0, 0,
     1942                    &addrlen);
    19541943                if (rc != EOK)
    19551944                        return rc;
    19561945               
    1957                 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(call), addr,
     1946                rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(*call), addr,
    19581947                    (socklen_t) addrlen, &device_id, &header, &headerlen);
    19591948                if (rc != EOK)
    19601949                        return rc;
    19611950               
    1962                 IPC_SET_DEVICE(answer, device_id);
    1963                 IP_SET_HEADERLEN(answer, headerlen);
     1951                IPC_SET_DEVICE(*answer, device_id);
     1952                IP_SET_HEADERLEN(*answer, headerlen);
    19641953               
    19651954                *answer_count = 2;
     
    19721961                return rc;
    19731962       
    1974         case NET_IL_PACKET_SPACE:
    1975                 rc = ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen,
     1963        case NET_IP_PACKET_SPACE:
     1964                rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen,
    19761965                    &prefix, &content, &suffix);
    19771966                if (rc != EOK)
    19781967                        return rc;
    19791968               
    1980                 IPC_SET_ADDR(answer, addrlen);
    1981                 IPC_SET_PREFIX(answer, prefix);
    1982                 IPC_SET_CONTENT(answer, content);
    1983                 IPC_SET_SUFFIX(answer, suffix);
     1969                IPC_SET_ADDR(*answer, addrlen);
     1970                IPC_SET_PREFIX(*answer, prefix);
     1971                IPC_SET_CONTENT(*answer, content);
     1972                IPC_SET_SUFFIX(*answer, suffix);
    19841973                *answer_count = 4;
    19851974                return EOK;
    19861975       
    1987         case NET_IL_MTU_CHANGED:
    1988                 return ip_mtu_changed_message(IPC_GET_DEVICE(call),
    1989                     IPC_GET_MTU(call));
     1976        case NET_IP_SEND:
     1977                rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1978                    IPC_GET_PACKET(*call));
     1979                if (rc != EOK)
     1980                        return rc;
     1981               
     1982                return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
     1983                    IPC_GET_ERROR(*call));
    19901984        }
    19911985       
     
    19931987}
    19941988
    1995 /** Default thread for new connections.
    1996  *
    1997  * @param[in] iid       The initial message identifier.
    1998  * @param[in] icall     The initial message call structure.
    1999  */
    2000 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    2001 {
    2002         /*
    2003          * Accept the connection
    2004          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    2005          */
    2006         ipc_answer_0(iid, EOK);
    2007        
    2008         while (true) {
    2009                 ipc_call_t answer;
    2010                 int answer_count;
    2011                
    2012                 /* Clear the answer structure */
    2013                 refresh_answer(&answer, &answer_count);
    2014                
    2015                 /* Fetch the next message */
    2016                 ipc_call_t call;
    2017                 ipc_callid_t callid = async_get_call(&call);
    2018                
    2019                 /* Process the message */
    2020                 int res = il_module_message_standalone(callid, &call, &answer,
    2021                     &answer_count);
    2022                
    2023                 /*
    2024                  * End if told to either by the message or the processing
    2025                  * result.
    2026                  */
    2027                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
    2028                     (res == EHANGUP)) {
    2029                         return;
    2030                 }
    2031                
    2032                 /* Answer the message */
    2033                 answer_call(callid, res, &answer, answer_count);
    2034         }
    2035 }
    2036 
    2037 /** Starts the module.
    2038  *
    2039  * @returns EOK on success.
    2040  * @returns Other error codes as defined for each specific module start function.
    2041  */
    20421989int main(int argc, char *argv[])
    20431990{
    2044         int rc;
    2045        
    20461991        /* Start the module */
    2047         rc = il_module_start_standalone(il_client_connection);
    2048         return rc;
     1992        return il_module_start(SERVICE_IP);
    20491993}
    20501994
Note: See TracChangeset for help on using the changeset viewer.