Ignore:
File:
1 edited

Legend:

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

    r5fe7692 r7880d58  
    3636 */
    3737
     38#include "ip.h"
     39#include "ip_module.h"
     40
    3841#include <async.h>
    3942#include <errno.h>
     
    4144#include <stdio.h>
    4245#include <str.h>
     46#include <ipc/ipc.h>
    4347#include <ipc/services.h>
    4448#include <ipc/net.h>
     
    4852#include <sys/types.h>
    4953#include <byteorder.h>
    50 #include "ip.h"
    5154
    5255#include <adt/measured_strings.h>
     
    6669#include <net_checksum.h>
    6770#include <icmp_client.h>
    68 #include <icmp_remote.h>
     71#include <icmp_interface.h>
     72#include <il_interface.h>
    6973#include <ip_client.h>
    7074#include <ip_interface.h>
    7175#include <ip_header.h>
    7276#include <net_interface.h>
    73 #include <nil_remote.h>
    74 #include <tl_remote.h>
     77#include <nil_interface.h>
     78#include <tl_interface.h>
    7579#include <packet_remote.h>
    76 #include <il_remote.h>
    77 #include <il_skel.h>
     80#include <il_local.h>
    7881
    7982/** IP module name. */
     
    119122INT_MAP_IMPLEMENT(ip_protos, ip_proto_t);
    120123GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t);
    121 
    122 static void ip_receiver(ipc_callid_t, ipc_call_t *);
    123124
    124125/** Releases the packet and returns the result.
     
    243244}
    244245
    245 int il_initialize(int net_phone)
    246 {
     246/** Initializes the IP module.
     247 *
     248 * @param[in] client_connection The client connection processing function. The
     249 *                      module skeleton propagates its own one.
     250 * @return              EOK on success.
     251 * @return              ENOMEM if there is not enough memory left.
     252 */
     253int ip_initialize(async_client_conn_t client_connection)
     254{
     255        int rc;
     256
    247257        fibril_rwlock_initialize(&ip_globals.lock);
    248258        fibril_rwlock_write_lock(&ip_globals.lock);
    249259        fibril_rwlock_initialize(&ip_globals.protos_lock);
    250260        fibril_rwlock_initialize(&ip_globals.netifs_lock);
    251        
    252         ip_globals.net_phone = net_phone;
    253261        ip_globals.packet_counter = 0;
    254262        ip_globals.gateway.address.s_addr = 0;
     
    256264        ip_globals.gateway.gateway.s_addr = 0;
    257265        ip_globals.gateway.netif = NULL;
    258        
    259         int rc = ip_netifs_initialize(&ip_globals.netifs);
     266        ip_globals.client_connection = client_connection;
     267       
     268        rc = ip_netifs_initialize(&ip_globals.netifs);
    260269        if (rc != EOK)
    261270                goto out;
     
    266275        if (rc != EOK)
    267276                goto out;
    268         rc = add_module(NULL, &ip_globals.modules, (uint8_t *) ARP_NAME,
    269             (uint8_t *) ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module);
     277        rc = add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME,
     278            SERVICE_ARP, 0, arp_connect_module);
    270279
    271280out:
     
    303312        measured_string_t names[] = {
    304313                {
    305                         (uint8_t *) "IPV",
     314                        (char *) "IPV",
    306315                        3
    307316                },
    308317                {
    309                         (uint8_t *) "IP_CONFIG",
     318                        (char *) "IP_CONFIG",
    310319                        9
    311320                },
    312321                {
    313                         (uint8_t *) "IP_ADDR",
     322                        (char *) "IP_ADDR",
    314323                        7
    315324                },
    316325                {
    317                         (uint8_t *) "IP_NETMASK",
     326                        (char *) "IP_NETMASK",
    318327                        10
    319328                },
    320329                {
    321                         (uint8_t *) "IP_GATEWAY",
     330                        (char *) "IP_GATEWAY",
    322331                        10
    323332                },
    324333                {
    325                         (uint8_t *) "IP_BROADCAST",
     334                        (char *) "IP_BROADCAST",
    326335                        12
    327336                },
    328337                {
    329                         (uint8_t *) "ARP",
     338                        (char *) "ARP",
    330339                        3
    331340                },
    332341                {
    333                         (uint8_t *) "IP_ROUTING",
     342                        (char *) "IP_ROUTING",
    334343                        10
    335344                }
     
    337346        measured_string_t *configuration;
    338347        size_t count = sizeof(names) / sizeof(measured_string_t);
    339         uint8_t *data;
     348        char *data;
    340349        measured_string_t address;
    341350        ip_route_t *route;
     
    359368        if (configuration) {
    360369                if (configuration[0].value)
    361                         ip_netif->ipv = strtol((char *) configuration[0].value, NULL, 0);
    362                
    363                 ip_netif->dhcp = !str_lcmp((char *) configuration[1].value, "dhcp",
     370                        ip_netif->ipv = strtol(configuration[0].value, NULL, 0);
     371
     372                ip_netif->dhcp = !str_lcmp(configuration[1].value, "dhcp",
    364373                    configuration[1].length);
    365374               
     
    385394                        }
    386395                       
    387                         if ((inet_pton(AF_INET, (char *) configuration[2].value,
     396                        if ((inet_pton(AF_INET, configuration[2].value,
    388397                            (uint8_t *) &route->address.s_addr) != EOK) ||
    389                             (inet_pton(AF_INET, (char *) configuration[3].value,
     398                            (inet_pton(AF_INET, configuration[3].value,
    390399                            (uint8_t *) &route->netmask.s_addr) != EOK) ||
    391                             (inet_pton(AF_INET, (char *) configuration[4].value,
     400                            (inet_pton(AF_INET, configuration[4].value,
    392401                            (uint8_t *) &gateway.s_addr) == EINVAL) ||
    393                             (inet_pton(AF_INET, (char *) configuration[5].value,
     402                            (inet_pton(AF_INET, configuration[5].value,
    394403                            (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL))
    395404                            {
     
    422431        ip_netif->phone = nil_bind_service(ip_netif->service,
    423432            (sysarg_t) ip_netif->device_id, SERVICE_IP,
    424             ip_receiver);
     433            ip_globals.client_connection);
    425434        if (ip_netif->phone < 0) {
    426435                printf("Failed to contact the nil service %d\n",
     
    432441        if (ip_netif->arp) {
    433442                if (route) {
    434                         address.value = (uint8_t *) &route->address.s_addr;
     443                        address.value = (char *) &route->address.s_addr;
    435444                        address.length = sizeof(in_addr_t);
    436445                       
     
    468477                ip_globals.gateway.gateway.s_addr = gateway.s_addr;
    469478                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);
    475479        }
    476480
     
    478482}
    479483
    480 static 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;
     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 */
     491static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
     492{
     493        ip_netif_t *netif;
    501494
    502495        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    503 
    504         rc = ip_netif_initialize(ip_netif);
    505         if (rc != EOK) {
     496        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     497        if (!netif) {
    506498                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    507                 ip_routes_destroy(&ip_netif->routes, free);
    508                 free(ip_netif);
    509                 return rc;
    510         }
    511         if (ip_netif->arp)
    512                 ip_netif->arp->usage++;
    513 
    514         // print the settings
    515         printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
    516             NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
    517             ip_netif->dhcp ? "dhcp" : "static");
    518        
    519         // TODO ipv6 addresses
    520        
    521         char address[INET_ADDRSTRLEN];
    522         char netmask[INET_ADDRSTRLEN];
    523         char gateway[INET_ADDRSTRLEN];
    524        
    525         for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) {
    526                 route = ip_routes_get_index(&ip_netif->routes, index);
    527                 if (route) {
    528                         inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr,
    529                             address, INET_ADDRSTRLEN);
    530                         inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr,
    531                             netmask, INET_ADDRSTRLEN);
    532                         inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr,
    533                             gateway, INET_ADDRSTRLEN);
    534                         printf("%s: Route %d (address: %s, netmask: %s, "
    535                             "gateway: %s)\n", NAME, index, address, netmask,
    536                             gateway);
    537                 }
    538         }
    539        
    540         inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address,
    541             INET_ADDRSTRLEN);
     499                return ENOENT;
     500        }
     501        netif->packet_dimension.content = mtu;
    542502        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    543503
    544         printf("%s: Broadcast (%s)\n", NAME, address);
     504        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
    545505
    546506        return EOK;
    547507}
    548508
    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  */
    557 static 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)
     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 */
     516static 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 */
     544static ip_header_t *
     545ip_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)
    564551                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  */
    584 static ip_route_t *ip_find_route(in_addr_t destination) {
    585         int index;
    586         ip_route_t *route;
    587         ip_netif_t *netif;
    588 
    589         // start with the last netif - the newest one
    590         index = ip_netifs_count(&ip_globals.netifs) - 1;
    591         while (index >= 0) {
    592                 netif = ip_netifs_get_index(&ip_globals.netifs, index);
    593                 if (netif && (netif->state == NETIF_ACTIVE)) {
    594                         route = ip_netif_find_route(netif, destination);
    595                         if (route)
    596                                 return route;
    597                 }
    598                 index--;
    599         }
    600 
    601         return &ip_globals.gateway;
    602 }
    603 
    604 /** Returns the network interface's IP address.
    605  *
    606  * @param[in] netif     The network interface.
    607  * @return              The IP address.
    608  * @return              NULL if no IP address was found.
    609  */
    610 static 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;
     552        memcpy(middle, last, IP_HEADER_LENGTH(last));
     553        middle->flags |= IPFLAG_MORE_FRAGMENTS;
     554        return middle;
    616555}
    617556
     
    682621 *                      function.
    683622 */
    684 static int ip_prepare_packet(in_addr_t *source, in_addr_t dest,
    685     packet_t *packet, measured_string_t *destination)
     623static int
     624ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet,
     625    measured_string_t *destination)
    686626{
    687627        size_t length;
     
    812752 *                      function.
    813753 */
    814 static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
     754static int
     755ip_fragment_packet_data(packet_t *packet, packet_t *new_packet,
    815756    ip_header_t *header, ip_header_t *new_header, size_t length,
    816757    const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen)
     
    846787
    847788        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  */
    858 static 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;
    869789}
    870790
     
    1071991 *                      function.
    1072992 */
    1073 static 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)
     993static int
     994ip_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)
    1075996{
    1076997        measured_string_t destination;
    1077998        measured_string_t *translation;
    1078         uint8_t *data;
     999        char *data;
    10791000        int phone;
    10801001        int rc;
     
    10831004        if (netif->arp && (route->address.s_addr != dest.s_addr)) {
    10841005                destination.value = route->gateway.s_addr ?
    1085                     (uint8_t *) &route->gateway.s_addr : (uint8_t *) &dest.s_addr;
     1006                    (char *) &route->gateway.s_addr : (char *) &dest.s_addr;
    10861007                destination.length = sizeof(dest.s_addr);
    10871008
     
    11351056}
    11361057
    1137 static int ip_send_msg_local(int il_phone, device_id_t device_id,
    1138     packet_t *packet, services_t sender, services_t error)
     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 */
     1066static ip_route_t *
     1067ip_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 */
     1094static 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 */
     1120static 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 */
     1144static int
     1145ip_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
     1178static int
     1179ip_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
     1247static int
     1248ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet,
     1249    services_t sender, services_t error)
    11391250{
    11401251        int addrlen;
     
    11771288        if (device_id > 0) {
    11781289                netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1179                 route = ip_netif_find_route(netif, *dest);
     1290                route = ip_netif_find_route(netif, * dest);
    11801291                if (netif && !route && (ip_globals.gateway.netif == netif))
    11811292                        route = &ip_globals.gateway;
     
    12071318                }
    12081319        }
    1209        
     1320
    12101321        // if the local host is the destination
    12111322        if ((route->address.s_addr == dest->s_addr) &&
     
    12401351}
    12411352
    1242 /** Updates the device state.
    1243  *
     1353/** Returns the device packet dimensions for sending.
     1354 *
     1355 * @param[in] phone     The service module phone.
     1356 * @param[in] message   The service specific message.
    12441357 * @param[in] device_id The device identifier.
    1245  * @param[in] state     The new state value.
     1358 * @param[out] addr_len The minimum reserved address length.
     1359 * @param[out] prefix   The minimum reserved prefix size.
     1360 * @param[out] content  The maximum content size.
     1361 * @param[out] suffix   The minimum reserved suffix size.
    12461362 * @return              EOK on success.
    1247  * @return              ENOENT if device is not found.
    1248  */
    1249 static int ip_device_state_message(device_id_t device_id, device_state_t state)
     1363 */
     1364static int
     1365ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix,
     1366    size_t *content, size_t *suffix)
    12501367{
    12511368        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);
     1369        int index;
     1370
     1371        if (!addr_len || !prefix || !content || !suffix)
     1372                return EBADMEM;
     1373
     1374        *content = IP_MAX_CONTENT - IP_PREFIX;
     1375        fibril_rwlock_read_lock(&ip_globals.netifs_lock);
     1376        if (device_id < 0) {
     1377                *addr_len = IP_ADDR;
     1378                *prefix = 0;
     1379                *suffix = 0;
     1380
     1381                for (index = ip_netifs_count(&ip_globals.netifs) - 1;
     1382                    index >= 0; index--) {
     1383                        netif = ip_netifs_get_index(&ip_globals.netifs, index);
     1384                        if (!netif)
     1385                                continue;
     1386                       
     1387                        if (netif->packet_dimension.addr_len > *addr_len)
     1388                                *addr_len = netif->packet_dimension.addr_len;
     1389                       
     1390                        if (netif->packet_dimension.prefix > *prefix)
     1391                                *prefix = netif->packet_dimension.prefix;
     1392                               
     1393                        if (netif->packet_dimension.suffix > *suffix)
     1394                                *suffix = netif->packet_dimension.suffix;
     1395                }
     1396
     1397                *prefix = *prefix + IP_PREFIX;
     1398                *suffix = *suffix + IP_SUFFIX;
     1399        } else {
     1400                netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1401                if (!netif) {
     1402                        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
     1403                        return ENOENT;
     1404                }
     1405
     1406                *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?
     1407                    netif->packet_dimension.addr_len : IP_ADDR;
     1408                *prefix = netif->packet_dimension.prefix + IP_PREFIX;
     1409                *suffix = netif->packet_dimension.suffix + IP_SUFFIX;
     1410        }
     1411        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    12641412
    12651413        return EOK;
     
    13011449 *                      tl_received_msg() function.
    13021450 */
    1303 static int ip_deliver_local(device_id_t device_id, packet_t *packet,
    1304     ip_header_t *header, services_t error)
     1451static int
     1452ip_deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header,
     1453    services_t error)
    13051454{
    13061455        ip_proto_t *proto;
     
    14021551 *                      is disabled.
    14031552 */
    1404 static int ip_process_packet(device_id_t device_id, packet_t *packet)
     1553static int
     1554ip_process_packet(device_id_t device_id, packet_t *packet)
    14051555{
    14061556        ip_header_t *header;
     
    14121562        socklen_t addrlen;
    14131563        int rc;
    1414        
     1564
    14151565        header = (ip_header_t *) packet_get_data(packet);
    14161566        if (!header)
     
    14381588                return EINVAL;
    14391589        }
    1440        
     1590
    14411591        // process ipopt and get destination
    14421592        dest = ip_get_destination(header);
     
    14591609        if (rc != EOK)
    14601610                return rc;
    1461        
     1611
    14621612        route = ip_find_route(dest);
    14631613        if (!route) {
     
    14911641        return ENOENT;
    14921642}
    1493 
    1494 /** Returns the device packet dimensions for sending.
    1495  *
    1496  * @param[in] phone     The service module phone.
    1497  * @param[in] message   The service specific message.
    1498  * @param[in] device_id The device identifier.
    1499  * @param[out] addr_len The minimum reserved address length.
    1500  * @param[out] prefix   The minimum reserved prefix size.
    1501  * @param[out] content  The maximum content size.
    1502  * @param[out] suffix   The minimum reserved suffix size.
    1503  * @return              EOK on success.
    1504  */
    1505 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,
    1506     size_t *prefix, size_t *content, size_t *suffix)
    1507 {
    1508         ip_netif_t *netif;
    1509         int index;
    1510 
    1511         if (!addr_len || !prefix || !content || !suffix)
    1512                 return EBADMEM;
    1513 
    1514         *content = IP_MAX_CONTENT - IP_PREFIX;
    1515         fibril_rwlock_read_lock(&ip_globals.netifs_lock);
    1516         if (device_id < 0) {
    1517                 *addr_len = IP_ADDR;
    1518                 *prefix = 0;
    1519                 *suffix = 0;
    1520 
    1521                 for (index = ip_netifs_count(&ip_globals.netifs) - 1;
    1522                     index >= 0; index--) {
    1523                         netif = ip_netifs_get_index(&ip_globals.netifs, index);
    1524                         if (!netif)
    1525                                 continue;
    1526                        
    1527                         if (netif->packet_dimension.addr_len > *addr_len)
    1528                                 *addr_len = netif->packet_dimension.addr_len;
    1529                        
    1530                         if (netif->packet_dimension.prefix > *prefix)
    1531                                 *prefix = netif->packet_dimension.prefix;
    1532                                
    1533                         if (netif->packet_dimension.suffix > *suffix)
    1534                                 *suffix = netif->packet_dimension.suffix;
    1535                 }
    1536 
    1537                 *prefix = *prefix + IP_PREFIX;
    1538                 *suffix = *suffix + IP_SUFFIX;
    1539         } else {
    1540                 netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1541                 if (!netif) {
    1542                         fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    1543                         return ENOENT;
    1544                 }
    1545 
    1546                 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?
    1547                     netif->packet_dimension.addr_len : IP_ADDR;
    1548                 *prefix = netif->packet_dimension.prefix + IP_PREFIX;
    1549                 *suffix = netif->packet_dimension.suffix + IP_SUFFIX;
    1550         }
    1551         fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    1552 
    1553         return EOK;
    1554 }
    1555 
    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.
    1560  * @return              EOK on success.
    1561  * @return              ENOENT if device is not found.
    1562  */
    1563 static 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  */
    1587 static 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.
    1643  */
    1644 static int
    1645 ip_register(int protocol, services_t service, int phone,
    1646     tl_received_msg_t received_msg)
    1647 {
    1648         ip_proto_t *proto;
    1649         int index;
    1650 
    1651         if (!protocol || !service || ((phone < 0) && !received_msg))
    1652                 return EINVAL;
    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 
    16781643
    16791644static int
     
    17911756                    (header->destination_address & route->netmask.s_addr))) {
    17921757                        // clear the ARP mapping if any
    1793                         address.value = (uint8_t *) &header->destination_address;
     1758                        address.value = (char *) &header->destination_address;
    17941759                        address.length = sizeof(header->destination_address);
    17951760                        arp_clear_address_req(netif->arp->phone,
     
    18761841}
    18771842
     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 */
     1859static 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
    18781872/** Processes the IP message.
    18791873 *
     
    18871881 *
    18881882 * @see ip_interface.h
    1889  * @see il_remote.h
     1883 * @see il_interface.h
    18901884 * @see IS_NET_IP_MESSAGE()
    18911885 */
    1892 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    1893     size_t *answer_count)
     1886int
     1887ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     1888    int *answer_count)
    18941889{
    18951890        packet_t *packet;
    18961891        struct sockaddr *addr;
    1897         void *header;
    1898         size_t headerlen;
    18991892        size_t addrlen;
    19001893        size_t prefix;
    19011894        size_t suffix;
    19021895        size_t content;
     1896        void *header;
     1897        size_t headerlen;
    19031898        device_id_t device_id;
    19041899        int rc;
     
    19101905       
    19111906        case IPC_M_CONNECT_TO_ME:
    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));
     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:
     1915                rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1916                    IPC_GET_PACKET(call));
     1917                if (rc != EOK)
     1918                        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);
    19181932       
    19191933        case NET_IP_RECEIVED_ERROR:
    19201934                rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1921                     IPC_GET_PACKET(*call));
     1935                    IPC_GET_PACKET(call));
    19221936                if (rc != EOK)
    19231937                        return rc;
    1924                 return ip_received_error_msg_local(0, IPC_GET_DEVICE(*call),
    1925                     packet, IPC_GET_TARGET(*call), IPC_GET_ERROR(*call));
     1938                return ip_received_error_msg_local(0, IPC_GET_DEVICE(call),
     1939                    packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));
    19261940       
    19271941        case NET_IP_ADD_ROUTE:
    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));
     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));
    19311945
    19321946        case NET_IP_SET_GATEWAY:
    1933                 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call),
    1934                     IP_GET_GATEWAY(*call));
     1947                return ip_set_gateway_req_local(0, IPC_GET_DEVICE(call),
     1948                    IP_GET_GATEWAY(call));
    19351949
    19361950        case NET_IP_GET_ROUTE:
     
    19401954                        return rc;
    19411955               
    1942                 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(*call), addr,
     1956                rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(call), addr,
    19431957                    (socklen_t) addrlen, &device_id, &header, &headerlen);
    19441958                if (rc != EOK)
    19451959                        return rc;
    19461960               
    1947                 IPC_SET_DEVICE(*answer, device_id);
    1948                 IP_SET_HEADERLEN(*answer, headerlen);
     1961                IPC_SET_DEVICE(answer, device_id);
     1962                IP_SET_HEADERLEN(answer, headerlen);
    19491963               
    19501964                *answer_count = 2;
     
    19571971                return rc;
    19581972       
    1959         case NET_IP_PACKET_SPACE:
    1960                 rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen,
     1973        case NET_IL_PACKET_SPACE:
     1974                rc = ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen,
    19611975                    &prefix, &content, &suffix);
    19621976                if (rc != EOK)
    19631977                        return rc;
    19641978               
    1965                 IPC_SET_ADDR(*answer, addrlen);
    1966                 IPC_SET_PREFIX(*answer, prefix);
    1967                 IPC_SET_CONTENT(*answer, content);
    1968                 IPC_SET_SUFFIX(*answer, suffix);
     1979                IPC_SET_ADDR(answer, addrlen);
     1980                IPC_SET_PREFIX(answer, prefix);
     1981                IPC_SET_CONTENT(answer, content);
     1982                IPC_SET_SUFFIX(answer, suffix);
    19691983                *answer_count = 4;
    19701984                return EOK;
    19711985       
    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;
     1986        case NET_IL_MTU_CHANGED:
     1987                return ip_mtu_changed_message(IPC_GET_DEVICE(call),
     1988                    IPC_GET_MTU(call));
     1989        }
     1990       
     1991        return ENOTSUP;
     1992}
     1993
     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 */
     1999static 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;
    19772010               
    1978                 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
    1979                     IPC_GET_ERROR(*call));
    1980         }
    1981        
    1982         return ENOTSUP;
    1983 }
    1984 
     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 */
    19852041int main(int argc, char *argv[])
    19862042{
     2043        int rc;
     2044       
    19872045        /* Start the module */
    1988         return il_module_start(SERVICE_IP);
     2046        rc = il_module_start_standalone(il_client_connection);
     2047        return rc;
    19892048}
    19902049
Note: See TracChangeset for help on using the changeset viewer.