Ignore:
File:
1 edited

Legend:

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

    r014dd57b r7880d58  
    3535 * @see arp.h
    3636 */
     37
     38#include "ip.h"
     39#include "ip_module.h"
    3740
    3841#include <async.h>
     
    4952#include <sys/types.h>
    5053#include <byteorder.h>
    51 #include "ip.h"
    5254
    5355#include <adt/measured_strings.h>
     
    6870#include <icmp_client.h>
    6971#include <icmp_interface.h>
     72#include <il_interface.h>
    7073#include <ip_client.h>
    7174#include <ip_interface.h>
    7275#include <ip_header.h>
    7376#include <net_interface.h>
    74 #include <nil_remote.h>
    75 #include <tl_remote.h>
     77#include <nil_interface.h>
     78#include <tl_interface.h>
    7679#include <packet_remote.h>
    77 #include <il_remote.h>
    78 #include <il_skel.h>
     80#include <il_local.h>
    7981
    8082/** IP module name. */
     
    120122INT_MAP_IMPLEMENT(ip_protos, ip_proto_t);
    121123GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t);
    122 
    123 static void ip_receiver(ipc_callid_t, ipc_call_t *);
    124124
    125125/** Releases the packet and returns the result.
     
    244244}
    245245
    246 int il_initialize(int net_phone)
    247 {
     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
    248257        fibril_rwlock_initialize(&ip_globals.lock);
    249258        fibril_rwlock_write_lock(&ip_globals.lock);
    250259        fibril_rwlock_initialize(&ip_globals.protos_lock);
    251260        fibril_rwlock_initialize(&ip_globals.netifs_lock);
    252        
    253         ip_globals.net_phone = net_phone;
    254261        ip_globals.packet_counter = 0;
    255262        ip_globals.gateway.address.s_addr = 0;
     
    257264        ip_globals.gateway.gateway.s_addr = 0;
    258265        ip_globals.gateway.netif = NULL;
    259        
    260         int rc = ip_netifs_initialize(&ip_globals.netifs);
     266        ip_globals.client_connection = client_connection;
     267       
     268        rc = ip_netifs_initialize(&ip_globals.netifs);
    261269        if (rc != EOK)
    262270                goto out;
     
    267275        if (rc != EOK)
    268276                goto out;
    269         rc = add_module(NULL, &ip_globals.modules, (uint8_t *) ARP_NAME,
    270             (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);
    271279
    272280out:
     
    304312        measured_string_t names[] = {
    305313                {
    306                         (uint8_t *) "IPV",
     314                        (char *) "IPV",
    307315                        3
    308316                },
    309317                {
    310                         (uint8_t *) "IP_CONFIG",
     318                        (char *) "IP_CONFIG",
    311319                        9
    312320                },
    313321                {
    314                         (uint8_t *) "IP_ADDR",
     322                        (char *) "IP_ADDR",
    315323                        7
    316324                },
    317325                {
    318                         (uint8_t *) "IP_NETMASK",
     326                        (char *) "IP_NETMASK",
    319327                        10
    320328                },
    321329                {
    322                         (uint8_t *) "IP_GATEWAY",
     330                        (char *) "IP_GATEWAY",
    323331                        10
    324332                },
    325333                {
    326                         (uint8_t *) "IP_BROADCAST",
     334                        (char *) "IP_BROADCAST",
    327335                        12
    328336                },
    329337                {
    330                         (uint8_t *) "ARP",
     338                        (char *) "ARP",
    331339                        3
    332340                },
    333341                {
    334                         (uint8_t *) "IP_ROUTING",
     342                        (char *) "IP_ROUTING",
    335343                        10
    336344                }
     
    338346        measured_string_t *configuration;
    339347        size_t count = sizeof(names) / sizeof(measured_string_t);
    340         uint8_t *data;
     348        char *data;
    341349        measured_string_t address;
    342350        ip_route_t *route;
     
    360368        if (configuration) {
    361369                if (configuration[0].value)
    362                         ip_netif->ipv = strtol((char *) configuration[0].value, NULL, 0);
    363                
    364                 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",
    365373                    configuration[1].length);
    366374               
     
    386394                        }
    387395                       
    388                         if ((inet_pton(AF_INET, (char *) configuration[2].value,
     396                        if ((inet_pton(AF_INET, configuration[2].value,
    389397                            (uint8_t *) &route->address.s_addr) != EOK) ||
    390                             (inet_pton(AF_INET, (char *) configuration[3].value,
     398                            (inet_pton(AF_INET, configuration[3].value,
    391399                            (uint8_t *) &route->netmask.s_addr) != EOK) ||
    392                             (inet_pton(AF_INET, (char *) configuration[4].value,
     400                            (inet_pton(AF_INET, configuration[4].value,
    393401                            (uint8_t *) &gateway.s_addr) == EINVAL) ||
    394                             (inet_pton(AF_INET, (char *) configuration[5].value,
     402                            (inet_pton(AF_INET, configuration[5].value,
    395403                            (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL))
    396404                            {
     
    423431        ip_netif->phone = nil_bind_service(ip_netif->service,
    424432            (sysarg_t) ip_netif->device_id, SERVICE_IP,
    425             ip_receiver);
     433            ip_globals.client_connection);
    426434        if (ip_netif->phone < 0) {
    427435                printf("Failed to contact the nil service %d\n",
     
    433441        if (ip_netif->arp) {
    434442                if (route) {
    435                         address.value = (uint8_t *) &route->address.s_addr;
     443                        address.value = (char *) &route->address.s_addr;
    436444                        address.length = sizeof(in_addr_t);
    437445                       
     
    469477                ip_globals.gateway.gateway.s_addr = gateway.s_addr;
    470478                ip_globals.gateway.netif = ip_netif;
    471                
    472                 char defgateway[INET_ADDRSTRLEN];
    473                 inet_ntop(AF_INET, (uint8_t *) &gateway.s_addr,
    474                     defgateway, INET_ADDRSTRLEN);
    475                 printf("%s: Default gateway (%s)\n", NAME, defgateway);
    476479        }
    477480
     
    479482}
    480483
    481 static int ip_device_req_local(int il_phone, device_id_t device_id,
    482     services_t netif)
    483 {
    484         ip_netif_t *ip_netif;
    485         ip_route_t *route;
    486         int index;
    487         int rc;
    488 
    489         ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t));
    490         if (!ip_netif)
    491                 return ENOMEM;
    492 
    493         rc = ip_routes_initialize(&ip_netif->routes);
    494         if (rc != EOK) {
    495                 free(ip_netif);
    496                 return rc;
    497         }
    498 
    499         ip_netif->device_id = device_id;
    500         ip_netif->service = netif;
    501         ip_netif->state = NETIF_STOPPED;
     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;
    502494
    503495        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    504 
    505         rc = ip_netif_initialize(ip_netif);
    506         if (rc != EOK) {
     496        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     497        if (!netif) {
    507498                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    508                 ip_routes_destroy(&ip_netif->routes);
    509                 free(ip_netif);
    510                 return rc;
    511         }
    512         if (ip_netif->arp)
    513                 ip_netif->arp->usage++;
    514 
    515         // print the settings
    516         printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
    517             NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
    518             ip_netif->dhcp ? "dhcp" : "static");
    519        
    520         // TODO ipv6 addresses
    521        
    522         char address[INET_ADDRSTRLEN];
    523         char netmask[INET_ADDRSTRLEN];
    524         char gateway[INET_ADDRSTRLEN];
    525        
    526         for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) {
    527                 route = ip_routes_get_index(&ip_netif->routes, index);
    528                 if (route) {
    529                         inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr,
    530                             address, INET_ADDRSTRLEN);
    531                         inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr,
    532                             netmask, INET_ADDRSTRLEN);
    533                         inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr,
    534                             gateway, INET_ADDRSTRLEN);
    535                         printf("%s: Route %d (address: %s, netmask: %s, "
    536                             "gateway: %s)\n", NAME, index, address, netmask,
    537                             gateway);
    538                 }
    539         }
    540        
    541         inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address,
    542             INET_ADDRSTRLEN);
     499                return ENOENT;
     500        }
     501        netif->packet_dimension.content = mtu;
    543502        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    544503
    545         printf("%s: Broadcast (%s)\n", NAME, address);
     504        printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
    546505
    547506        return EOK;
    548507}
    549508
    550 /** Searches the network interfaces if there is a suitable route.
    551  *
    552  * @param[in] netif     The network interface to be searched for routes. May be
    553  *                      NULL.
    554  * @param[in] destination The destination address.
    555  * @return              The found route.
    556  * @return              NULL if no route was found.
    557  */
    558 static ip_route_t *ip_netif_find_route(ip_netif_t *netif,
    559     in_addr_t destination)
    560 {
    561         int index;
    562         ip_route_t *route;
    563        
    564         if (!netif)
     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)
    565551                return NULL;
    566        
    567         /* Start with the first one (the direct route) */
    568         for (index = 0; index < ip_routes_count(&netif->routes); index++) {
    569                 route = ip_routes_get_index(&netif->routes, index);
    570                 if ((route) &&
    571                     ((route->address.s_addr & route->netmask.s_addr) ==
    572                     (destination.s_addr & route->netmask.s_addr)))
    573                         return route;
    574         }
    575 
    576         return NULL;
    577 }
    578 
    579 /** Searches all network interfaces if there is a suitable route.
    580  *
    581  * @param[in] destination The destination address.
    582  * @return              The found route.
    583  * @return              NULL if no route was found.
    584  */
    585 static ip_route_t *ip_find_route(in_addr_t destination) {
    586         int index;
    587         ip_route_t *route;
    588         ip_netif_t *netif;
    589 
    590         // start with the last netif - the newest one
    591         index = ip_netifs_count(&ip_globals.netifs) - 1;
    592         while (index >= 0) {
    593                 netif = ip_netifs_get_index(&ip_globals.netifs, index);
    594                 if (netif && (netif->state == NETIF_ACTIVE)) {
    595                         route = ip_netif_find_route(netif, destination);
    596                         if (route)
    597                                 return route;
    598                 }
    599                 index--;
    600         }
    601 
    602         return &ip_globals.gateway;
    603 }
    604 
    605 /** Returns the network interface's IP address.
    606  *
    607  * @param[in] netif     The network interface.
    608  * @return              The IP address.
    609  * @return              NULL if no IP address was found.
    610  */
    611 static in_addr_t *ip_netif_address(ip_netif_t *netif)
    612 {
    613         ip_route_t *route;
    614 
    615         route = ip_routes_get_index(&netif->routes, 0);
    616         return route ? &route->address : NULL;
     552        memcpy(middle, last, IP_HEADER_LENGTH(last));
     553        middle->flags |= IPFLAG_MORE_FRAGMENTS;
     554        return middle;
    617555}
    618556
     
    683621 *                      function.
    684622 */
    685 static int ip_prepare_packet(in_addr_t *source, in_addr_t dest,
    686     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)
    687626{
    688627        size_t length;
     
    813752 *                      function.
    814753 */
    815 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,
    816756    ip_header_t *header, ip_header_t *new_header, size_t length,
    817757    const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen)
     
    847787
    848788        return pq_insert_after(packet, new_packet);
    849 }
    850 
    851 /** Prefixes a middle fragment header based on the last fragment header to the
    852  * packet.
    853  *
    854  * @param[in] packet    The packet to be prefixed.
    855  * @param[in] last      The last header to be copied.
    856  * @return              The prefixed middle header.
    857  * @return              NULL on error.
    858  */
    859 static ip_header_t *ip_create_middle_header(packet_t *packet,
    860     ip_header_t *last)
    861 {
    862         ip_header_t *middle;
    863 
    864         middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));
    865         if (!middle)
    866                 return NULL;
    867         memcpy(middle, last, IP_HEADER_LENGTH(last));
    868         middle->flags |= IPFLAG_MORE_FRAGMENTS;
    869         return middle;
    870789}
    871790
     
    1072991 *                      function.
    1073992 */
    1074 static int ip_send_route(packet_t *packet, ip_netif_t *netif,
    1075     ip_route_t *route, in_addr_t *src, in_addr_t dest, services_t error)
     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)
    1076996{
    1077997        measured_string_t destination;
    1078998        measured_string_t *translation;
    1079         uint8_t *data;
     999        char *data;
    10801000        int phone;
    10811001        int rc;
     
    10841004        if (netif->arp && (route->address.s_addr != dest.s_addr)) {
    10851005                destination.value = route->gateway.s_addr ?
    1086                     (uint8_t *) &route->gateway.s_addr : (uint8_t *) &dest.s_addr;
     1006                    (char *) &route->gateway.s_addr : (char *) &dest.s_addr;
    10871007                destination.length = sizeof(dest.s_addr);
    10881008
     
    11361056}
    11371057
    1138 static int ip_send_msg_local(int il_phone, device_id_t device_id,
    1139     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)
    11401250{
    11411251        int addrlen;
     
    11781288        if (device_id > 0) {
    11791289                netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1180                 route = ip_netif_find_route(netif, *dest);
     1290                route = ip_netif_find_route(netif, * dest);
    11811291                if (netif && !route && (ip_globals.gateway.netif == netif))
    11821292                        route = &ip_globals.gateway;
     
    12081318                }
    12091319        }
    1210        
     1320
    12111321        // if the local host is the destination
    12121322        if ((route->address.s_addr == dest->s_addr) &&
     
    12411351}
    12421352
    1243 /** Updates the device state.
    1244  *
     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.
    12451357 * @param[in] device_id The device identifier.
    1246  * @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.
    12471362 * @return              EOK on success.
    1248  * @return              ENOENT if device is not found.
    1249  */
    1250 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)
    12511367{
    12521368        ip_netif_t *netif;
    1253 
    1254         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    1255         // find the device
    1256         netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1257         if (!netif) {
    1258                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1259                 return ENOENT;
    1260         }
    1261         netif->state = state;
    1262         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1263 
    1264         printf("%s: Device %d changed state to %d\n", NAME, device_id, state);
     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);
    12651412
    12661413        return EOK;
     
    13021449 *                      tl_received_msg() function.
    13031450 */
    1304 static int ip_deliver_local(device_id_t device_id, packet_t *packet,
    1305     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)
    13061454{
    13071455        ip_proto_t *proto;
     
    14031551 *                      is disabled.
    14041552 */
    1405 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)
    14061555{
    14071556        ip_header_t *header;
     
    14131562        socklen_t addrlen;
    14141563        int rc;
    1415        
     1564
    14161565        header = (ip_header_t *) packet_get_data(packet);
    14171566        if (!header)
     
    14391588                return EINVAL;
    14401589        }
    1441        
     1590
    14421591        // process ipopt and get destination
    14431592        dest = ip_get_destination(header);
     
    14601609        if (rc != EOK)
    14611610                return rc;
    1462        
     1611
    14631612        route = ip_find_route(dest);
    14641613        if (!route) {
     
    14921641        return ENOENT;
    14931642}
    1494 
    1495 /** Returns the device packet dimensions for sending.
    1496  *
    1497  * @param[in] phone     The service module phone.
    1498  * @param[in] message   The service specific message.
    1499  * @param[in] device_id The device identifier.
    1500  * @param[out] addr_len The minimum reserved address length.
    1501  * @param[out] prefix   The minimum reserved prefix size.
    1502  * @param[out] content  The maximum content size.
    1503  * @param[out] suffix   The minimum reserved suffix size.
    1504  * @return              EOK on success.
    1505  */
    1506 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,
    1507     size_t *prefix, size_t *content, size_t *suffix)
    1508 {
    1509         ip_netif_t *netif;
    1510         int index;
    1511 
    1512         if (!addr_len || !prefix || !content || !suffix)
    1513                 return EBADMEM;
    1514 
    1515         *content = IP_MAX_CONTENT - IP_PREFIX;
    1516         fibril_rwlock_read_lock(&ip_globals.netifs_lock);
    1517         if (device_id < 0) {
    1518                 *addr_len = IP_ADDR;
    1519                 *prefix = 0;
    1520                 *suffix = 0;
    1521 
    1522                 for (index = ip_netifs_count(&ip_globals.netifs) - 1;
    1523                     index >= 0; index--) {
    1524                         netif = ip_netifs_get_index(&ip_globals.netifs, index);
    1525                         if (!netif)
    1526                                 continue;
    1527                        
    1528                         if (netif->packet_dimension.addr_len > *addr_len)
    1529                                 *addr_len = netif->packet_dimension.addr_len;
    1530                        
    1531                         if (netif->packet_dimension.prefix > *prefix)
    1532                                 *prefix = netif->packet_dimension.prefix;
    1533                                
    1534                         if (netif->packet_dimension.suffix > *suffix)
    1535                                 *suffix = netif->packet_dimension.suffix;
    1536                 }
    1537 
    1538                 *prefix = *prefix + IP_PREFIX;
    1539                 *suffix = *suffix + IP_SUFFIX;
    1540         } else {
    1541                 netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1542                 if (!netif) {
    1543                         fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    1544                         return ENOENT;
    1545                 }
    1546 
    1547                 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?
    1548                     netif->packet_dimension.addr_len : IP_ADDR;
    1549                 *prefix = netif->packet_dimension.prefix + IP_PREFIX;
    1550                 *suffix = netif->packet_dimension.suffix + IP_SUFFIX;
    1551         }
    1552         fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    1553 
    1554         return EOK;
    1555 }
    1556 
    1557 /** Updates the device content length according to the new MTU value.
    1558  *
    1559  * @param[in] device_id The device identifier.
    1560  * @param[in] mtu       The new mtu value.
    1561  * @return              EOK on success.
    1562  * @return              ENOENT if device is not found.
    1563  */
    1564 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)
    1565 {
    1566         ip_netif_t *netif;
    1567 
    1568         fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    1569         netif = ip_netifs_find(&ip_globals.netifs, device_id);
    1570         if (!netif) {
    1571                 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1572                 return ENOENT;
    1573         }
    1574         netif->packet_dimension.content = mtu;
    1575         fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    1576 
    1577         printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);
    1578 
    1579         return EOK;
    1580 }
    1581 
    1582 /** Process IPC messages from the registered device driver modules
    1583  *
    1584  * @param[in]     iid   Message identifier.
    1585  * @param[in,out] icall Message parameters.
    1586  *
    1587  */
    1588 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall)
    1589 {
    1590         packet_t *packet;
    1591         int rc;
    1592        
    1593         while (true) {
    1594                 switch (IPC_GET_IMETHOD(*icall)) {
    1595                 case NET_IL_DEVICE_STATE:
    1596                         rc = ip_device_state_message(IPC_GET_DEVICE(*icall),
    1597                             IPC_GET_STATE(*icall));
    1598                         ipc_answer_0(iid, (sysarg_t) rc);
    1599                         break;
    1600                
    1601                 case NET_IL_RECEIVED:
    1602                         rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1603                             IPC_GET_PACKET(*icall));
    1604                         if (rc == EOK) {
    1605                                 do {
    1606                                         packet_t *next = pq_detach(packet);
    1607                                         ip_process_packet(IPC_GET_DEVICE(*icall), packet);
    1608                                         packet = next;
    1609                                 } while (packet);
    1610                         }
    1611                        
    1612                         ipc_answer_0(iid, (sysarg_t) rc);
    1613                         break;
    1614                
    1615                 case NET_IL_MTU_CHANGED:
    1616                         rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall),
    1617                             IPC_GET_MTU(*icall));
    1618                         ipc_answer_0(iid, (sysarg_t) rc);
    1619                         break;
    1620                
    1621                 default:
    1622                         ipc_answer_0(iid, (sysarg_t) ENOTSUP);
    1623                 }
    1624                
    1625                 iid = async_get_call(icall);
    1626         }
    1627 }
    1628 
    1629 /** Registers the transport layer protocol.
    1630  *
    1631  * The traffic of this protocol will be supplied using either the receive
    1632  * function or IPC message.
    1633  *
    1634  * @param[in] protocol  The transport layer module protocol.
    1635  * @param[in] service   The transport layer module service.
    1636  * @param[in] phone     The transport layer module phone.
    1637  * @param[in] received_msg The receiving function.
    1638  * @return              EOK on success.
    1639  * @return              EINVAL if the protocol parameter and/or the service
    1640  *                      parameter is zero.
    1641  * @return              EINVAL if the phone parameter is not a positive number
    1642  *                      and the tl_receive_msg is NULL.
    1643  * @return              ENOMEM if there is not enough memory left.
    1644  */
    1645 static int
    1646 ip_register(int protocol, services_t service, int phone,
    1647     tl_received_msg_t received_msg)
    1648 {
    1649         ip_proto_t *proto;
    1650         int index;
    1651 
    1652         if (!protocol || !service || ((phone < 0) && !received_msg))
    1653                 return EINVAL;
    1654 
    1655         proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
    1656         if (!proto)
    1657                 return ENOMEM;
    1658 
    1659         proto->protocol = protocol;
    1660         proto->service = service;
    1661         proto->phone = phone;
    1662         proto->received_msg = received_msg;
    1663 
    1664         fibril_rwlock_write_lock(&ip_globals.protos_lock);
    1665         index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
    1666         if (index < 0) {
    1667                 fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    1668                 free(proto);
    1669                 return index;
    1670         }
    1671         fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    1672 
    1673         printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
    1674             NAME, proto->protocol, proto->phone);
    1675 
    1676         return EOK;
    1677 }
    1678 
    16791643
    16801644static int
     
    17921756                    (header->destination_address & route->netmask.s_addr))) {
    17931757                        // clear the ARP mapping if any
    1794                         address.value = (uint8_t *) &header->destination_address;
     1758                        address.value = (char *) &header->destination_address;
    17951759                        address.length = sizeof(header->destination_address);
    17961760                        arp_clear_address_req(netif->arp->phone,
     
    18771841}
    18781842
     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
    18791872/** Processes the IP message.
    18801873 *
     
    18881881 *
    18891882 * @see ip_interface.h
    1890  * @see il_remote.h
     1883 * @see il_interface.h
    18911884 * @see IS_NET_IP_MESSAGE()
    18921885 */
    1893 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    1894     size_t *answer_count)
     1886int
     1887ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     1888    int *answer_count)
    18951889{
    18961890        packet_t *packet;
    18971891        struct sockaddr *addr;
    1898         void *header;
    1899         size_t headerlen;
    19001892        size_t addrlen;
    19011893        size_t prefix;
    19021894        size_t suffix;
    19031895        size_t content;
     1896        void *header;
     1897        size_t headerlen;
    19041898        device_id_t device_id;
    19051899        int rc;
     
    19111905       
    19121906        case IPC_M_CONNECT_TO_ME:
    1913                 return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
    1914                     IPC_GET_PHONE(*call), NULL);
    1915        
    1916         case NET_IP_DEVICE:
    1917                 return ip_device_req_local(0, IPC_GET_DEVICE(*call),
    1918                     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);
    19191932       
    19201933        case NET_IP_RECEIVED_ERROR:
    19211934                rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1922                     IPC_GET_PACKET(*call));
     1935                    IPC_GET_PACKET(call));
    19231936                if (rc != EOK)
    19241937                        return rc;
    1925                 return ip_received_error_msg_local(0, IPC_GET_DEVICE(*call),
    1926                     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));
    19271940       
    19281941        case NET_IP_ADD_ROUTE:
    1929                 return ip_add_route_req_local(0, IPC_GET_DEVICE(*call),
    1930                     IP_GET_ADDRESS(*call), IP_GET_NETMASK(*call),
    1931                     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));
    19321945
    19331946        case NET_IP_SET_GATEWAY:
    1934                 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call),
    1935                     IP_GET_GATEWAY(*call));
     1947                return ip_set_gateway_req_local(0, IPC_GET_DEVICE(call),
     1948                    IP_GET_GATEWAY(call));
    19361949
    19371950        case NET_IP_GET_ROUTE:
     
    19411954                        return rc;
    19421955               
    1943                 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,
    19441957                    (socklen_t) addrlen, &device_id, &header, &headerlen);
    19451958                if (rc != EOK)
    19461959                        return rc;
    19471960               
    1948                 IPC_SET_DEVICE(*answer, device_id);
    1949                 IP_SET_HEADERLEN(*answer, headerlen);
     1961                IPC_SET_DEVICE(answer, device_id);
     1962                IP_SET_HEADERLEN(answer, headerlen);
    19501963               
    19511964                *answer_count = 2;
     
    19581971                return rc;
    19591972       
    1960         case NET_IP_PACKET_SPACE:
    1961                 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,
    19621975                    &prefix, &content, &suffix);
    19631976                if (rc != EOK)
    19641977                        return rc;
    19651978               
    1966                 IPC_SET_ADDR(*answer, addrlen);
    1967                 IPC_SET_PREFIX(*answer, prefix);
    1968                 IPC_SET_CONTENT(*answer, content);
    1969                 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);
    19701983                *answer_count = 4;
    19711984                return EOK;
    19721985       
    1973         case NET_IP_SEND:
    1974                 rc = packet_translate_remote(ip_globals.net_phone, &packet,
    1975                     IPC_GET_PACKET(*call));
    1976                 if (rc != EOK)
    1977                         return rc;
     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;
    19782010               
    1979                 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
    1980                     IPC_GET_ERROR(*call));
    1981         }
    1982        
    1983         return ENOTSUP;
    1984 }
    1985 
     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 */
    19862041int main(int argc, char *argv[])
    19872042{
     2043        int rc;
     2044       
    19882045        /* Start the module */
    1989         return il_module_start(SERVICE_IP);
     2046        rc = il_module_start_standalone(il_client_connection);
     2047        return rc;
    19902048}
    19912049
Note: See TracChangeset for help on using the changeset viewer.