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


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

streamline internetworking layer

  • IPC method renaming

NET_IL_DEVICE → NET_IP_DEVICE
NET_IL_PACKET_SPACE → NET_IP_PACKET_SPACE
NET_IL_SEND → NET_IP_SEND

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

  • implelement common IL module skeleton
  • small improvements in the comments of the NETIF and NIL skeletons
  • IL modules now use a separate receiver function for the NET_IL_* calls
File:
1 edited

Legend:

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

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