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


Ignore:
Timestamp:
2011-02-03T05:11:01Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ba38f72c
Parents:
22027b6e (diff), 86d7bfa (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:

Merge mainline changes.

File:
1 edited

Legend:

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

    r22027b6e r8b5690f  
    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. */
     
    122119INT_MAP_IMPLEMENT(ip_protos, ip_proto_t);
    123120GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t);
     121
     122static void ip_receiver(ipc_callid_t, ipc_call_t *);
    124123
    125124/** Releases the packet and returns the result.
     
    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  * @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 
     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;
     
    431422        ip_netif->phone = nil_bind_service(ip_netif->service,
    432423            (sysarg_t) ip_netif->device_id, SERVICE_IP,
    433             ip_globals.client_connection);
     424            ip_receiver);
    434425        if (ip_netif->phone < 0) {
    435426                printf("Failed to contact the nil service %d\n",
     
    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  * @return              EOK on success.
    489  * @return              ENOENT if device is not found.
    490  */
    491 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
    492 {
     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;
     501
     502        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     503
     504        rc = ip_netif_initialize(ip_netif);
     505        if (rc != EOK) {
     506                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     507                ip_routes_destroy(&ip_netif->routes);
     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);
     542        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     543
     544        printf("%s: Broadcast (%s)\n", NAME, address);
     545
     546        return EOK;
     547}
     548
     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)
     564                return NULL;
     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;
    493587        ip_netif_t *netif;
    494588
    495         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    496         netif = ip_netifs_find(&ip_globals.netifs, device_id);
    497         if (!netif) {
    498                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    499                 return ENOENT;
    500         }
    501         netif->packet_dimension.content = mtu;
    502         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    503 
    504         printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
    505 
    506         return EOK;
    507 }
    508 
    509 /** Updates the device state.
    510  *
    511  * @param[in] device_id The device identifier.
    512  * @param[in] state     The new state value.
    513  * @return              EOK on success.
    514  * @return              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_t *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  * @return              The prefixed middle header.
    542  * @return              NULL on error.
    543  */
    544 static ip_header_t *
    545 ip_create_middle_header(packet_t *packet, ip_header_t *last)
    546 {
    547         ip_header_t *middle;
    548 
    549         middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));
    550         if (!middle)
    551                 return NULL;
    552         memcpy(middle, last, IP_HEADER_LENGTH(last));
    553         middle->flags |= IPFLAG_MORE_FRAGMENTS;
    554         return middle;
     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
     
    621682 *                      function.
    622683 */
    623 static int
    624 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet,
    625     measured_string_t *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;
     
    752812 *                      function.
    753813 */
    754 static int
    755 ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
     814static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
    756815    ip_header_t *header, ip_header_t *new_header, size_t length,
    757816    const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen)
     
    787846
    788847        return pq_insert_after(packet, new_packet);
     848}
     849
     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;
    789869}
    790870
     
    9911071 *                      function.
    9921072 */
    993 static int
    994 ip_send_route(packet_t *packet, ip_netif_t *netif, ip_route_t *route,
    995     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)
    9961075{
    9971076        measured_string_t destination;
     
    10561135}
    10571136
    1058 /** Searches the network interfaces if there is a suitable route.
    1059  *
    1060  * @param[in] netif     The network interface to be searched for routes. May be
    1061  *                      NULL.
    1062  * @param[in] destination The destination address.
    1063  * @return              The found route.
    1064  * @return              NULL if no route was found.
    1065  */
    1066 static ip_route_t *
    1067 ip_netif_find_route(ip_netif_t *netif, in_addr_t destination)
    1068 {
    1069         int index;
    1070         ip_route_t *route;
    1071 
    1072         if (!netif)
    1073                 return NULL;
    1074 
    1075         // start with the first one - the direct route
    1076         for (index = 0; index < ip_routes_count(&netif->routes); index++) {
    1077                 route = ip_routes_get_index(&netif->routes, index);
    1078                 if (route &&
    1079                     ((route->address.s_addr & route->netmask.s_addr) ==
    1080                     (destination.s_addr & route->netmask.s_addr))) {
    1081                         return route;
    1082                 }
    1083         }
    1084 
    1085         return NULL;
    1086 }
    1087 
    1088 /** Searches all network interfaces if there is a suitable route.
    1089  *
    1090  * @param[in] destination The destination address.
    1091  * @return              The found route.
    1092  * @return              NULL if no route was found.
    1093  */
    1094 static ip_route_t *ip_find_route(in_addr_t destination) {
    1095         int index;
    1096         ip_route_t *route;
    1097         ip_netif_t *netif;
    1098 
    1099         // start with the last netif - the newest one
    1100         index = ip_netifs_count(&ip_globals.netifs) - 1;
    1101         while (index >= 0) {
    1102                 netif = ip_netifs_get_index(&ip_globals.netifs, index);
    1103                 if (netif && (netif->state == NETIF_ACTIVE)) {
    1104                         route = ip_netif_find_route(netif, destination);
    1105                         if (route)
    1106                                 return route;
    1107                 }
    1108                 index--;
    1109         }
    1110 
    1111         return &ip_globals.gateway;
    1112 }
    1113 
    1114 /** Returns the network interface's IP address.
    1115  *
    1116  * @param[in] netif     The network interface.
    1117  * @return              The IP address.
    1118  * @return              NULL if no IP address was found.
    1119  */
    1120 static in_addr_t *ip_netif_address(ip_netif_t *netif)
    1121 {
    1122         ip_route_t *route;
    1123 
    1124         route = ip_routes_get_index(&netif->routes, 0);
    1125         return route ? &route->address : NULL;
    1126 }
    1127 
    1128 /** Registers the transport layer protocol.
    1129  *
    1130  * The traffic of this protocol will be supplied using either the receive
    1131  * function or IPC message.
    1132  *
    1133  * @param[in] protocol  The transport layer module protocol.
    1134  * @param[in] service   The transport layer module service.
    1135  * @param[in] phone     The transport layer module phone.
    1136  * @param[in] received_msg The receiving function.
    1137  * @return              EOK on success.
    1138  * @return              EINVAL if the protocol parameter and/or the service
    1139  *                      parameter is zero.
    1140  * @return              EINVAL if the phone parameter is not a positive number
    1141  *                      and the tl_receive_msg is NULL.
    1142  * @return              ENOMEM if there is not enough memory left.
    1143  */
    1144 static int
    1145 ip_register(int protocol, services_t service, int phone,
    1146     tl_received_msg_t received_msg)
    1147 {
    1148         ip_proto_t *proto;
    1149         int index;
    1150 
    1151         if (!protocol || !service || ((phone < 0) && !received_msg))
    1152                 return EINVAL;
    1153 
    1154         proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
    1155         if (!proto)
    1156                 return ENOMEM;
    1157 
    1158         proto->protocol = protocol;
    1159         proto->service = service;
    1160         proto->phone = phone;
    1161         proto->received_msg = received_msg;
    1162 
    1163         fibril_rwlock_write_lock(&ip_globals.protos_lock);
    1164         index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
    1165         if (index < 0) {
    1166                 fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    1167                 free(proto);
    1168                 return index;
    1169         }
    1170         fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    1171 
    1172         printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
    1173             NAME, proto->protocol, proto->phone);
    1174 
    1175         return EOK;
    1176 }
    1177 
    1178 static int
    1179 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif)
    1180 {
    1181         ip_netif_t *ip_netif;
    1182         ip_route_t *route;
    1183         int index;
    1184         int rc;
    1185 
    1186         ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t));
    1187         if (!ip_netif)
    1188                 return ENOMEM;
    1189 
    1190         rc = ip_routes_initialize(&ip_netif->routes);
    1191         if (rc != EOK) {
    1192                 free(ip_netif);
    1193                 return rc;
    1194         }
    1195 
    1196         ip_netif->device_id = device_id;
    1197         ip_netif->service = netif;
    1198         ip_netif->state = NETIF_STOPPED;
    1199 
    1200         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    1201 
    1202         rc = ip_netif_initialize(ip_netif);
    1203         if (rc != EOK) {
    1204                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1205                 ip_routes_destroy(&ip_netif->routes);
    1206                 free(ip_netif);
    1207                 return rc;
    1208         }
    1209         if (ip_netif->arp)
    1210                 ip_netif->arp->usage++;
    1211 
    1212         // print the settings
    1213         printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
    1214             NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
    1215             ip_netif->dhcp ? "dhcp" : "static");
    1216        
    1217         // TODO ipv6 addresses
    1218        
    1219         char address[INET_ADDRSTRLEN];
    1220         char netmask[INET_ADDRSTRLEN];
    1221         char gateway[INET_ADDRSTRLEN];
    1222        
    1223         for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) {
    1224                 route = ip_routes_get_index(&ip_netif->routes, index);
    1225                 if (route) {
    1226                         inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr,
    1227                             address, INET_ADDRSTRLEN);
    1228                         inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr,
    1229                             netmask, INET_ADDRSTRLEN);
    1230                         inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr,
    1231                             gateway, INET_ADDRSTRLEN);
    1232                         printf("%s: Route %d (address: %s, netmask: %s, "
    1233                             "gateway: %s)\n", NAME, index, address, netmask,
    1234                             gateway);
    1235                 }
    1236         }
    1237        
    1238         inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address,
    1239             INET_ADDRSTRLEN);
    1240         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1241 
    1242         printf("%s: Broadcast (%s)\n", NAME, address);
    1243 
    1244         return EOK;
    1245 }
    1246 
    1247 static int
    1248 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet,
    1249     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)
    12501139{
    12511140        int addrlen;
     
    12881177        if (device_id > 0) {
    12891178                netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1290                 route = ip_netif_find_route(netif, * dest);
     1179                route = ip_netif_find_route(netif, *dest);
    12911180                if (netif && !route && (ip_globals.gateway.netif == netif))
    12921181                        route = &ip_globals.gateway;
     
    13181207                }
    13191208        }
    1320 
     1209       
    13211210        // if the local host is the destination
    13221211        if ((route->address.s_addr == dest->s_addr) &&
     
    13511240}
    13521241
     1242/** Updates the device state.
     1243 *
     1244 * @param[in] device_id The device identifier.
     1245 * @param[in] state     The new state value.
     1246 * @return              EOK on success.
     1247 * @return              ENOENT if device is not found.
     1248 */
     1249static int ip_device_state_message(device_id_t device_id, device_state_t state)
     1250{
     1251        ip_netif_t *netif;
     1252
     1253        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     1254        // find the device
     1255        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1256        if (!netif) {
     1257                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1258                return ENOENT;
     1259        }
     1260        netif->state = state;
     1261        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1262
     1263        printf("%s: Device %d changed state to %d\n", NAME, device_id, state);
     1264
     1265        return EOK;
     1266}
     1267
     1268/** Returns the packet destination address from the IP header.
     1269 *
     1270 * @param[in] header    The packet IP header to be read.
     1271 * @return              The packet destination address.
     1272 */
     1273static in_addr_t ip_get_destination(ip_header_t *header)
     1274{
     1275        in_addr_t destination;
     1276
     1277        // TODO search set ipopt route?
     1278        destination.s_addr = header->destination_address;
     1279        return destination;
     1280}
     1281
     1282/** Delivers the packet to the local host.
     1283 *
     1284 * The packet is either passed to another module or released on error.
     1285 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not
     1286 * found.
     1287 *
     1288 * @param[in] device_id The source device identifier.
     1289 * @param[in] packet    The packet to be delivered.
     1290 * @param[in] header    The first packet IP header. May be NULL.
     1291 * @param[in] error     The packet error service.
     1292 * @return              EOK on success.
     1293 * @return              ENOTSUP if the packet is a fragment.
     1294 * @return              EAFNOSUPPORT if the address family is not supported.
     1295 * @return              ENOENT if the target protocol is not found.
     1296 * @return              Other error codes as defined for the packet_set_addr()
     1297 *                      function.
     1298 * @return              Other error codes as defined for the packet_trim()
     1299 *                      function.
     1300 * @return              Other error codes as defined for the protocol specific
     1301 *                      tl_received_msg() function.
     1302 */
     1303static int ip_deliver_local(device_id_t device_id, packet_t *packet,
     1304    ip_header_t *header, services_t error)
     1305{
     1306        ip_proto_t *proto;
     1307        int phone;
     1308        services_t service;
     1309        tl_received_msg_t received_msg;
     1310        struct sockaddr *src;
     1311        struct sockaddr *dest;
     1312        struct sockaddr_in src_in;
     1313        struct sockaddr_in dest_in;
     1314        socklen_t addrlen;
     1315        int rc;
     1316
     1317        if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
     1318            IP_FRAGMENT_OFFSET(header)) {
     1319                // TODO fragmented
     1320                return ENOTSUP;
     1321        }
     1322       
     1323        switch (header->version) {
     1324        case IPVERSION:
     1325                addrlen = sizeof(src_in);
     1326                bzero(&src_in, addrlen);
     1327                src_in.sin_family = AF_INET;
     1328                memcpy(&dest_in, &src_in, addrlen);
     1329                memcpy(&src_in.sin_addr.s_addr, &header->source_address,
     1330                    sizeof(header->source_address));
     1331                memcpy(&dest_in.sin_addr.s_addr, &header->destination_address,
     1332                    sizeof(header->destination_address));
     1333                src = (struct sockaddr *) &src_in;
     1334                dest = (struct sockaddr *) &dest_in;
     1335                break;
     1336
     1337        default:
     1338                return ip_release_and_return(packet, EAFNOSUPPORT);
     1339        }
     1340
     1341        rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest,
     1342            addrlen);
     1343        if (rc != EOK)
     1344                return ip_release_and_return(packet, rc);
     1345
     1346        // trim padding if present
     1347        if (!error &&
     1348            (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) {
     1349                rc = packet_trim(packet, 0,
     1350                    packet_get_data_length(packet) - IP_TOTAL_LENGTH(header));
     1351                if (rc != EOK)
     1352                        return ip_release_and_return(packet, rc);
     1353        }
     1354
     1355        fibril_rwlock_read_lock(&ip_globals.protos_lock);
     1356
     1357        proto = ip_protos_find(&ip_globals.protos, header->protocol);
     1358        if (!proto) {
     1359                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1360                phone = ip_prepare_icmp_and_get_phone(error, packet, header);
     1361                if (phone >= 0) {
     1362                        // unreachable ICMP
     1363                        icmp_destination_unreachable_msg(phone,
     1364                            ICMP_PROT_UNREACH, 0, packet);
     1365                }
     1366                return ENOENT;
     1367        }
     1368
     1369        if (proto->received_msg) {
     1370                service = proto->service;
     1371                received_msg = proto->received_msg;
     1372                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1373                rc = received_msg(device_id, packet, service, error);
     1374        } else {
     1375                rc = tl_received_msg(proto->phone, device_id, packet,
     1376                    proto->service, error);
     1377                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1378        }
     1379
     1380        return rc;
     1381}
     1382
     1383/** Processes the received packet.
     1384 *
     1385 * The packet is either passed to another module or released on error.
     1386 *
     1387 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is
     1388 * invalid.
     1389 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two.
     1390 * The ICMP_HOST_UNREACH error notification may be sent if no route was found.
     1391 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for
     1392 * another host and the routing is disabled.
     1393 *
     1394 * @param[in] device_id The source device identifier.
     1395 * @param[in] packet    The received packet to be processed.
     1396 * @return              EOK on success.
     1397 * @return              EINVAL if the TTL is less than two.
     1398 * @return              EINVAL if the checksum is invalid.
     1399 * @return              EAFNOSUPPORT if the address family is not supported.
     1400 * @return              ENOENT if no route was found.
     1401 * @return              ENOENT if the packet is for another host and the routing
     1402 *                      is disabled.
     1403 */
     1404static int ip_process_packet(device_id_t device_id, packet_t *packet)
     1405{
     1406        ip_header_t *header;
     1407        in_addr_t dest;
     1408        ip_route_t *route;
     1409        int phone;
     1410        struct sockaddr *addr;
     1411        struct sockaddr_in addr_in;
     1412        socklen_t addrlen;
     1413        int rc;
     1414       
     1415        header = (ip_header_t *) packet_get_data(packet);
     1416        if (!header)
     1417                return ip_release_and_return(packet, ENOMEM);
     1418
     1419        // checksum
     1420        if ((header->header_checksum) &&
     1421            (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
     1422                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1423                if (phone >= 0) {
     1424                        // checksum error ICMP
     1425                        icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
     1426                            ((size_t) ((void *) &header->header_checksum)) -
     1427                            ((size_t) ((void *) header)), packet);
     1428                }
     1429                return EINVAL;
     1430        }
     1431
     1432        if (header->ttl <= 1) {
     1433                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1434                if (phone >= 0) {
     1435                        // ttl exceeded ICMP
     1436                        icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
     1437                }
     1438                return EINVAL;
     1439        }
     1440       
     1441        // process ipopt and get destination
     1442        dest = ip_get_destination(header);
     1443
     1444        // set the addrination address
     1445        switch (header->version) {
     1446        case IPVERSION:
     1447                addrlen = sizeof(addr_in);
     1448                bzero(&addr_in, addrlen);
     1449                addr_in.sin_family = AF_INET;
     1450                memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest));
     1451                addr = (struct sockaddr *) &addr_in;
     1452                break;
     1453
     1454        default:
     1455                return ip_release_and_return(packet, EAFNOSUPPORT);
     1456        }
     1457
     1458        rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen);
     1459        if (rc != EOK)
     1460                return rc;
     1461       
     1462        route = ip_find_route(dest);
     1463        if (!route) {
     1464                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1465                if (phone >= 0) {
     1466                        // unreachable ICMP
     1467                        icmp_destination_unreachable_msg(phone,
     1468                            ICMP_HOST_UNREACH, 0, packet);
     1469                }
     1470                return ENOENT;
     1471        }
     1472
     1473        if (route->address.s_addr == dest.s_addr) {
     1474                // local delivery
     1475                return ip_deliver_local(device_id, packet, header, 0);
     1476        }
     1477
     1478        if (route->netif->routing) {
     1479                header->ttl--;
     1480                return ip_send_route(packet, route->netif, route, NULL, dest,
     1481                    0);
     1482        }
     1483
     1484        phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1485        if (phone >= 0) {
     1486                // unreachable ICMP if no routing
     1487                icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
     1488                    packet);
     1489        }
     1490       
     1491        return ENOENT;
     1492}
     1493
    13531494/** Returns the device packet dimensions for sending.
    13541495 *
     
    13621503 * @return              EOK on success.
    13631504 */
    1364 static int
    1365 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix,
    1366     size_t *content, size_t *suffix)
     1505static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,
     1506    size_t *prefix, size_t *content, size_t *suffix)
    13671507{
    13681508        ip_netif_t *netif;
     
    14141554}
    14151555
    1416 /** Returns the packet destination address from the IP header.
    1417  *
    1418  * @param[in] header    The packet IP header to be read.
    1419  * @return              The packet destination address.
    1420  */
    1421 static in_addr_t ip_get_destination(ip_header_t *header)
    1422 {
    1423         in_addr_t destination;
    1424 
    1425         // TODO search set ipopt route?
    1426         destination.s_addr = header->destination_address;
    1427         return destination;
    1428 }
    1429 
    1430 /** Delivers the packet to the local host.
    1431  *
    1432  * The packet is either passed to another module or released on error.
    1433  * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not
    1434  * found.
    1435  *
    1436  * @param[in] device_id The source device identifier.
    1437  * @param[in] packet    The packet to be delivered.
    1438  * @param[in] header    The first packet IP header. May be NULL.
    1439  * @param[in] error     The packet error service.
     1556/** Updates the device content length according to the new MTU value.
     1557 *
     1558 * @param[in] device_id The device identifier.
     1559 * @param[in] mtu       The new mtu value.
    14401560 * @return              EOK on success.
    1441  * @return              ENOTSUP if the packet is a fragment.
    1442  * @return              EAFNOSUPPORT if the address family is not supported.
    1443  * @return              ENOENT if the target protocol is not found.
    1444  * @return              Other error codes as defined for the packet_set_addr()
    1445  *                      function.
    1446  * @return              Other error codes as defined for the packet_trim()
    1447  *                      function.
    1448  * @return              Other error codes as defined for the protocol specific
    1449  *                      tl_received_msg() function.
     1561 * @return              ENOENT if device is not found.
     1562 */
     1563static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
     1564{
     1565        ip_netif_t *netif;
     1566
     1567        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     1568        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1569        if (!netif) {
     1570                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1571                return ENOENT;
     1572        }
     1573        netif->packet_dimension.content = mtu;
     1574        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     1575
     1576        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
     1577
     1578        return EOK;
     1579}
     1580
     1581/** Process IPC messages from the registered device driver modules
     1582 *
     1583 * @param[in]     iid   Message identifier.
     1584 * @param[in,out] icall Message parameters.
     1585 *
     1586 */
     1587static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall)
     1588{
     1589        packet_t *packet;
     1590        int rc;
     1591       
     1592        while (true) {
     1593                switch (IPC_GET_IMETHOD(*icall)) {
     1594                case NET_IL_DEVICE_STATE:
     1595                        rc = ip_device_state_message(IPC_GET_DEVICE(*icall),
     1596                            IPC_GET_STATE(*icall));
     1597                        async_answer_0(iid, (sysarg_t) rc);
     1598                        break;
     1599               
     1600                case NET_IL_RECEIVED:
     1601                        rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1602                            IPC_GET_PACKET(*icall));
     1603                        if (rc == EOK) {
     1604                                do {
     1605                                        packet_t *next = pq_detach(packet);
     1606                                        ip_process_packet(IPC_GET_DEVICE(*icall), packet);
     1607                                        packet = next;
     1608                                } while (packet);
     1609                        }
     1610                       
     1611                        async_answer_0(iid, (sysarg_t) rc);
     1612                        break;
     1613               
     1614                case NET_IL_MTU_CHANGED:
     1615                        rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall),
     1616                            IPC_GET_MTU(*icall));
     1617                        async_answer_0(iid, (sysarg_t) rc);
     1618                        break;
     1619               
     1620                default:
     1621                        async_answer_0(iid, (sysarg_t) ENOTSUP);
     1622                }
     1623               
     1624                iid = async_get_call(icall);
     1625        }
     1626}
     1627
     1628/** Registers the transport layer protocol.
     1629 *
     1630 * The traffic of this protocol will be supplied using either the receive
     1631 * function or IPC message.
     1632 *
     1633 * @param[in] protocol  The transport layer module protocol.
     1634 * @param[in] service   The transport layer module service.
     1635 * @param[in] phone     The transport layer module phone.
     1636 * @param[in] received_msg The receiving function.
     1637 * @return              EOK on success.
     1638 * @return              EINVAL if the protocol parameter and/or the service
     1639 *                      parameter is zero.
     1640 * @return              EINVAL if the phone parameter is not a positive number
     1641 *                      and the tl_receive_msg is NULL.
     1642 * @return              ENOMEM if there is not enough memory left.
    14501643 */
    14511644static int
    1452 ip_deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header,
    1453     services_t error)
     1645ip_register(int protocol, services_t service, int phone,
     1646    tl_received_msg_t received_msg)
    14541647{
    14551648        ip_proto_t *proto;
    1456         int phone;
    1457         services_t service;
    1458         tl_received_msg_t received_msg;
    1459         struct sockaddr *src;
    1460         struct sockaddr *dest;
    1461         struct sockaddr_in src_in;
    1462         struct sockaddr_in dest_in;
    1463         socklen_t addrlen;
    1464         int rc;
    1465 
    1466         if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
    1467             IP_FRAGMENT_OFFSET(header)) {
    1468                 // TODO fragmented
    1469                 return ENOTSUP;
    1470         }
    1471        
    1472         switch (header->version) {
    1473         case IPVERSION:
    1474                 addrlen = sizeof(src_in);
    1475                 bzero(&src_in, addrlen);
    1476                 src_in.sin_family = AF_INET;
    1477                 memcpy(&dest_in, &src_in, addrlen);
    1478                 memcpy(&src_in.sin_addr.s_addr, &header->source_address,
    1479                     sizeof(header->source_address));
    1480                 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address,
    1481                     sizeof(header->destination_address));
    1482                 src = (struct sockaddr *) &src_in;
    1483                 dest = (struct sockaddr *) &dest_in;
    1484                 break;
    1485 
    1486         default:
    1487                 return ip_release_and_return(packet, EAFNOSUPPORT);
    1488         }
    1489 
    1490         rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest,
    1491             addrlen);
    1492         if (rc != EOK)
    1493                 return ip_release_and_return(packet, rc);
    1494 
    1495         // trim padding if present
    1496         if (!error &&
    1497             (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) {
    1498                 rc = packet_trim(packet, 0,
    1499                     packet_get_data_length(packet) - IP_TOTAL_LENGTH(header));
    1500                 if (rc != EOK)
    1501                         return ip_release_and_return(packet, rc);
    1502         }
    1503 
    1504         fibril_rwlock_read_lock(&ip_globals.protos_lock);
    1505 
    1506         proto = ip_protos_find(&ip_globals.protos, header->protocol);
    1507         if (!proto) {
    1508                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1509                 phone = ip_prepare_icmp_and_get_phone(error, packet, header);
    1510                 if (phone >= 0) {
    1511                         // unreachable ICMP
    1512                         icmp_destination_unreachable_msg(phone,
    1513                             ICMP_PROT_UNREACH, 0, packet);
    1514                 }
    1515                 return ENOENT;
    1516         }
    1517 
    1518         if (proto->received_msg) {
    1519                 service = proto->service;
    1520                 received_msg = proto->received_msg;
    1521                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1522                 rc = received_msg(device_id, packet, service, error);
    1523         } else {
    1524                 rc = tl_received_msg(proto->phone, device_id, packet,
    1525                     proto->service, error);
    1526                 fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1527         }
    1528 
    1529         return rc;
    1530 }
    1531 
    1532 /** Processes the received packet.
    1533  *
    1534  * The packet is either passed to another module or released on error.
    1535  *
    1536  * The ICMP_PARAM_POINTER error notification may be sent if the checksum is
    1537  * invalid.
    1538  * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two.
    1539  * The ICMP_HOST_UNREACH error notification may be sent if no route was found.
    1540  * The ICMP_HOST_UNREACH error notification may be sent if the packet is for
    1541  * another host and the routing is disabled.
    1542  *
    1543  * @param[in] device_id The source device identifier.
    1544  * @param[in] packet    The received packet to be processed.
    1545  * @return              EOK on success.
    1546  * @return              EINVAL if the TTL is less than two.
    1547  * @return              EINVAL if the checksum is invalid.
    1548  * @return              EAFNOSUPPORT if the address family is not supported.
    1549  * @return              ENOENT if no route was found.
    1550  * @return              ENOENT if the packet is for another host and the routing
    1551  *                      is disabled.
    1552  */
    1553 static int
    1554 ip_process_packet(device_id_t device_id, packet_t *packet)
    1555 {
    1556         ip_header_t *header;
    1557         in_addr_t dest;
    1558         ip_route_t *route;
    1559         int phone;
    1560         struct sockaddr *addr;
    1561         struct sockaddr_in addr_in;
    1562         socklen_t addrlen;
    1563         int rc;
    1564 
    1565         header = (ip_header_t *) packet_get_data(packet);
    1566         if (!header)
    1567                 return ip_release_and_return(packet, ENOMEM);
    1568 
    1569         // checksum
    1570         if ((header->header_checksum) &&
    1571             (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
    1572                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1573                 if (phone >= 0) {
    1574                         // checksum error ICMP
    1575                         icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
    1576                             ((size_t) ((void *) &header->header_checksum)) -
    1577                             ((size_t) ((void *) header)), packet);
    1578                 }
     1649        int index;
     1650
     1651        if (!protocol || !service || ((phone < 0) && !received_msg))
    15791652                return EINVAL;
    1580         }
    1581 
    1582         if (header->ttl <= 1) {
    1583                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1584                 if (phone >= 0) {
    1585                         // ttl exceeded ICMP
    1586                         icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
    1587                 }
    1588                 return EINVAL;
    1589         }
    1590 
    1591         // process ipopt and get destination
    1592         dest = ip_get_destination(header);
    1593 
    1594         // set the addrination address
    1595         switch (header->version) {
    1596         case IPVERSION:
    1597                 addrlen = sizeof(addr_in);
    1598                 bzero(&addr_in, addrlen);
    1599                 addr_in.sin_family = AF_INET;
    1600                 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest));
    1601                 addr = (struct sockaddr *) &addr_in;
    1602                 break;
    1603 
    1604         default:
    1605                 return ip_release_and_return(packet, EAFNOSUPPORT);
    1606         }
    1607 
    1608         rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen);
    1609         if (rc != EOK)
    1610                 return rc;
    1611 
    1612         route = ip_find_route(dest);
    1613         if (!route) {
    1614                 phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1615                 if (phone >= 0) {
    1616                         // unreachable ICMP
    1617                         icmp_destination_unreachable_msg(phone,
    1618                             ICMP_HOST_UNREACH, 0, packet);
    1619                 }
    1620                 return ENOENT;
    1621         }
    1622 
    1623         if (route->address.s_addr == dest.s_addr) {
    1624                 // local delivery
    1625                 return ip_deliver_local(device_id, packet, header, 0);
    1626         }
    1627 
    1628         if (route->netif->routing) {
    1629                 header->ttl--;
    1630                 return ip_send_route(packet, route->netif, route, NULL, dest,
    1631                     0);
    1632         }
    1633 
    1634         phone = ip_prepare_icmp_and_get_phone(0, packet, header);
    1635         if (phone >= 0) {
    1636                 // unreachable ICMP if no routing
    1637                 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
    1638                     packet);
    1639         }
    1640        
    1641         return ENOENT;
    1642 }
     1653
     1654        proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
     1655        if (!proto)
     1656                return ENOMEM;
     1657
     1658        proto->protocol = protocol;
     1659        proto->service = service;
     1660        proto->phone = phone;
     1661        proto->received_msg = received_msg;
     1662
     1663        fibril_rwlock_write_lock(&ip_globals.protos_lock);
     1664        index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
     1665        if (index < 0) {
     1666                fibril_rwlock_write_unlock(&ip_globals.protos_lock);
     1667                free(proto);
     1668                return index;
     1669        }
     1670        fibril_rwlock_write_unlock(&ip_globals.protos_lock);
     1671
     1672        printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
     1673            NAME, proto->protocol, proto->phone);
     1674
     1675        return EOK;
     1676}
     1677
    16431678
    16441679static int
     
    18411876}
    18421877
    1843 /** Processes the received IP packet or the packet queue one by one.
    1844  *
    1845  * The packet is either passed to another module or released on error.
    1846  *
    1847  * @param[in] device_id The source device identifier.
    1848  * @param[in,out] packet The received packet.
    1849  * @return              EOK on success and the packet is no longer needed.
    1850  * @return              EINVAL if the packet is too small to carry the IP
    1851  *                      packet.
    1852  * @return              EINVAL if the received address lengths differs from the
    1853  *                      registered values.
    1854  * @return              ENOENT if the device is not found in the cache.
    1855  * @return              ENOENT if the protocol for the device is not found in
    1856  *                      the cache.
    1857  * @return              ENOMEM if there is not enough memory left.
    1858  */
    1859 static int ip_receive_message(device_id_t device_id, packet_t *packet)
    1860 {
    1861         packet_t *next;
    1862 
    1863         do {
    1864                 next = pq_detach(packet);
    1865                 ip_process_packet(device_id, packet);
    1866                 packet = next;
    1867         } while (packet);
    1868 
    1869         return EOK;
    1870 }
    1871 
    18721878/** Processes the IP message.
    18731879 *
     
    18811887 *
    18821888 * @see ip_interface.h
    1883  * @see il_interface.h
     1889 * @see il_remote.h
    18841890 * @see IS_NET_IP_MESSAGE()
    18851891 */
    1886 int
    1887 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    1888     int *answer_count)
     1892int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     1893    size_t *answer_count)
    18891894{
    18901895        packet_t *packet;
    18911896        struct sockaddr *addr;
     1897        void *header;
     1898        size_t headerlen;
    18921899        size_t addrlen;
    18931900        size_t prefix;
    18941901        size_t suffix;
    18951902        size_t content;
    1896         void *header;
    1897         size_t headerlen;
    18981903        device_id_t device_id;
    18991904        int rc;
     
    19051910       
    19061911        case IPC_M_CONNECT_TO_ME:
    1907                 return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call),
    1908                     IPC_GET_PHONE(call), NULL);
    1909        
    1910         case NET_IL_DEVICE:
    1911                 return ip_device_req_local(0, IPC_GET_DEVICE(call),
    1912                     IPC_GET_SERVICE(call));
    1913        
    1914         case NET_IL_SEND:
     1912                return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
     1913                    IPC_GET_PHONE(*call), NULL);
     1914       
     1915        case NET_IP_DEVICE:
     1916                return ip_device_req_local(0, IPC_GET_DEVICE(*call),
     1917                    IPC_GET_SERVICE(*call));
     1918       
     1919        case NET_IP_RECEIVED_ERROR:
    19151920                rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1916                     IPC_GET_PACKET(call));
     1921                    IPC_GET_PACKET(*call));
    19171922                if (rc != EOK)
    19181923                        return rc;
    1919                 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0,
    1920                     IPC_GET_ERROR(call));
    1921        
    1922         case NET_IL_DEVICE_STATE:
    1923                 return ip_device_state_message(IPC_GET_DEVICE(call),
    1924                     IPC_GET_STATE(call));
    1925        
    1926         case NET_IL_RECEIVED:
    1927                 rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1928                     IPC_GET_PACKET(call));
    1929                 if (rc != EOK)
    1930                         return rc;
    1931                 return ip_receive_message(IPC_GET_DEVICE(call), packet);
    1932        
    1933         case NET_IP_RECEIVED_ERROR:
    1934                 rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1935                     IPC_GET_PACKET(call));
    1936                 if (rc != EOK)
    1937                         return rc;
    1938                 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call),
    1939                     packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));
     1924                return ip_received_error_msg_local(0, IPC_GET_DEVICE(*call),
     1925                    packet, IPC_GET_TARGET(*call), IPC_GET_ERROR(*call));
    19401926       
    19411927        case NET_IP_ADD_ROUTE:
    1942                 return ip_add_route_req_local(0, IPC_GET_DEVICE(call),
    1943                     IP_GET_ADDRESS(call), IP_GET_NETMASK(call),
    1944                     IP_GET_GATEWAY(call));
     1928                return ip_add_route_req_local(0, IPC_GET_DEVICE(*call),
     1929                    IP_GET_ADDRESS(*call), IP_GET_NETMASK(*call),
     1930                    IP_GET_GATEWAY(*call));
    19451931
    19461932        case NET_IP_SET_GATEWAY:
    1947                 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(call),
    1948                     IP_GET_GATEWAY(call));
     1933                return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call),
     1934                    IP_GET_GATEWAY(*call));
    19491935
    19501936        case NET_IP_GET_ROUTE:
     
    19541940                        return rc;
    19551941               
    1956                 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(call), addr,
     1942                rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(*call), addr,
    19571943                    (socklen_t) addrlen, &device_id, &header, &headerlen);
    19581944                if (rc != EOK)
    19591945                        return rc;
    19601946               
    1961                 IPC_SET_DEVICE(answer, device_id);
    1962                 IP_SET_HEADERLEN(answer, headerlen);
     1947                IPC_SET_DEVICE(*answer, device_id);
     1948                IP_SET_HEADERLEN(*answer, headerlen);
    19631949               
    19641950                *answer_count = 2;
     
    19711957                return rc;
    19721958       
    1973         case NET_IL_PACKET_SPACE:
    1974                 rc = ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen,
     1959        case NET_IP_PACKET_SPACE:
     1960                rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen,
    19751961                    &prefix, &content, &suffix);
    19761962                if (rc != EOK)
    19771963                        return rc;
    19781964               
    1979                 IPC_SET_ADDR(answer, addrlen);
    1980                 IPC_SET_PREFIX(answer, prefix);
    1981                 IPC_SET_CONTENT(answer, content);
    1982                 IPC_SET_SUFFIX(answer, suffix);
     1965                IPC_SET_ADDR(*answer, addrlen);
     1966                IPC_SET_PREFIX(*answer, prefix);
     1967                IPC_SET_CONTENT(*answer, content);
     1968                IPC_SET_SUFFIX(*answer, suffix);
    19831969                *answer_count = 4;
    19841970                return EOK;
    19851971       
    1986         case NET_IL_MTU_CHANGED:
    1987                 return ip_mtu_changed_message(IPC_GET_DEVICE(call),
    1988                     IPC_GET_MTU(call));
     1972        case NET_IP_SEND:
     1973                rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1974                    IPC_GET_PACKET(*call));
     1975                if (rc != EOK)
     1976                        return rc;
     1977               
     1978                return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
     1979                    IPC_GET_ERROR(*call));
    19891980        }
    19901981       
     
    19921983}
    19931984
    1994 /** Default thread for new connections.
    1995  *
    1996  * @param[in] iid       The initial message identifier.
    1997  * @param[in] icall     The initial message call structure.
    1998  */
    1999 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    2000 {
    2001         /*
    2002          * Accept the connection
    2003          *  - Answer the first IPC_M_CONNECT_ME_TO call.
    2004          */
    2005         ipc_answer_0(iid, EOK);
    2006        
    2007         while (true) {
    2008                 ipc_call_t answer;
    2009                 int answer_count;
    2010                
    2011                 /* Clear the answer structure */
    2012                 refresh_answer(&answer, &answer_count);
    2013                
    2014                 /* Fetch the next message */
    2015                 ipc_call_t call;
    2016                 ipc_callid_t callid = async_get_call(&call);
    2017                
    2018                 /* Process the message */
    2019                 int res = il_module_message_standalone(callid, &call, &answer,
    2020                     &answer_count);
    2021                
    2022                 /*
    2023                  * End if told to either by the message or the processing
    2024                  * result.
    2025                  */
    2026                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
    2027                     (res == EHANGUP)) {
    2028                         return;
    2029                 }
    2030                
    2031                 /* Answer the message */
    2032                 answer_call(callid, res, &answer, answer_count);
    2033         }
    2034 }
    2035 
    2036 /** Starts the module.
    2037  *
    2038  * @return EOK on success.
    2039  * @return Other error codes as defined for each specific module start function.
    2040  */
    20411985int main(int argc, char *argv[])
    20421986{
    2043         int rc;
    2044        
    20451987        /* Start the module */
    2046         rc = il_module_start_standalone(il_client_connection);
    2047         return rc;
     1988        return il_module_start(SERVICE_IP);
    20481989}
    20491990
Note: See TracChangeset for help on using the changeset viewer.