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


Ignore:
Timestamp:
2010-03-07T22:51:38Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
60ab6c3
Parents:
b5cbff4 (diff), 31c80a5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~lukasmejdrech/helenos/network.

File:
1 edited

Legend:

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

    rb5cbff4 r71b00dcc  
    108108/** IP packet address length.
    109109 */
    110 #define IP_ADDR                                                 sizeof( struct sockaddr_in6 )
     110#define IP_ADDR                                                 sizeof(struct sockaddr_in6)
    111111
    112112/** IP packet prefix length.
    113113 */
    114 #define IP_PREFIX                                               sizeof( ip_header_t )
     114#define IP_PREFIX                                               sizeof(ip_header_t)
    115115
    116116/** IP packet suffix length.
     
    124124/** The IP localhost address.
    125125 */
    126 #define IPV4_LOCALHOST_ADDRESS  htonl(( 127 << 24 ) + 1 )
     126#define IPV4_LOCALHOST_ADDRESS  htonl((127 << 24) + 1)
    127127
    128128/** IP global data.
     
    130130ip_globals_t    ip_globals;
    131131
    132 DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
    133 
    134 INT_MAP_IMPLEMENT( ip_protos, ip_proto_t )
    135 
    136 GENERIC_FIELD_IMPLEMENT( ip_routes, ip_route_t )
     132DEVICE_MAP_IMPLEMENT(ip_netifs, ip_netif_t)
     133
     134INT_MAP_IMPLEMENT(ip_protos, ip_proto_t)
     135
     136GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t)
    137137
    138138/** Updates the device content length according to the new MTU value.
     
    142142 *  @returns ENOENT if device is not found.
    143143 */
    144 int     ip_mtu_changed_message( device_id_t device_id, size_t mtu );
     144int ip_mtu_changed_message(device_id_t device_id, size_t mtu);
    145145
    146146/** Updates the device state.
     
    150150 *  @returns ENOENT if device is not found.
    151151 */
    152 int     ip_device_state_message( device_id_t device_id, device_state_t state );
     152int ip_device_state_message(device_id_t device_id, device_state_t state);
    153153
    154154/** Returns the device packet dimensions for sending.
     
    162162 *  @returns EOK on success.
    163163 */
    164 int     ip_packet_size_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix );
     164int ip_packet_size_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix);
    165165
    166166/** Registers the transport layer protocol.
     
    175175 *  @returns ENOMEM if there is not enough memory left.
    176176 */
    177 int     ip_register( int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg );
     177int ip_register(int protocol, services_t service, int phone, tl_received_msg_t tl_received_msg);
    178178
    179179/** Initializes a new network interface specific data.
     
    192192 *  @returns Other error codes as defined for the nil_packet_size_req() function.
    193193 */
    194 int     ip_netif_initialize( ip_netif_ref ip_netif );
     194int ip_netif_initialize(ip_netif_ref ip_netif);
    195195
    196196/** Sends the packet or the packet queue via the specified route.
     
    206206 *  @returns Other error codes as defined for the ip_prepare_packet() function.
    207207 */
    208 int     ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error );
     208int ip_send_route(packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error);
    209209
    210210/** Prepares the outgoing packet or the packet queue.
     
    222222 *  @returns Other error codes as defined for the packet_set_addr() function.
    223223 */
    224 int     ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination );
     224int ip_prepare_packet(in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination);
    225225
    226226/** Checks the packet queue lengths and fragments the packets if needed.
     
    235235 *  @returns NULL if there are no packets left.
    236236 */
    237 packet_t        ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error );
     237packet_t ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error);
    238238
    239239/** Checks the packet length and fragments it if needed.
     
    255255 *  @returns Other error codes as defined for the ip_fragment_packet_data() function.
    256256 */
    257 int     ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len );
     257int ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len);
    258258
    259259/** Fragments the packet from the end.
     
    271271 *  @returns Other error codes as defined for the pq_insert_after() function.
    272272 */
    273 int     ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen );
     273int ip_fragment_packet_data(packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen);
    274274
    275275/** Prefixes a middle fragment header based on the last fragment header to the packet.
     
    279279 *  @returns NULL on error.
    280280 */
    281 ip_header_ref   ip_create_middle_header( packet_t packet, ip_header_ref last );
     281ip_header_ref ip_create_middle_header(packet_t packet, ip_header_ref last);
    282282
    283283/** Copies the fragment header.
     
    286286 *  @param[in] first The original header to be copied.
    287287 */
    288 void ip_create_last_header( ip_header_ref last, ip_header_ref first );
     288void ip_create_last_header(ip_header_ref last, ip_header_ref first);
    289289
    290290/** Returns the network interface's IP address.
     
    293293 *  @returns NULL if no IP address was found.
    294294 */
    295 in_addr_t *     ip_netif_address( ip_netif_ref netif );
     295in_addr_t * ip_netif_address(ip_netif_ref netif);
    296296
    297297/** Searches all network interfaces if there is a suitable route.
     
    300300 *  @returns NULL if no route was found.
    301301 */
    302 ip_route_ref    ip_find_route( in_addr_t destination );
     302ip_route_ref ip_find_route(in_addr_t destination);
    303303
    304304/** Searches the network interfaces if there is a suitable route.
     
    308308 *  @returns NULL if no route was found.
    309309 */
    310 ip_route_ref    ip_netif_find_route( ip_netif_ref netif, in_addr_t destination );
     310ip_route_ref ip_netif_find_route(ip_netif_ref netif, in_addr_t destination);
    311311
    312312/** Processes the received IP packet or the packet queue one by one.
     
    321321 *  @returns ENOMEM if there is not enough memory left.
    322322 */
    323 int     ip_receive_message( device_id_t device_id, packet_t packet );
     323int ip_receive_message(device_id_t device_id, packet_t packet);
    324324
    325325/** Processes the received packet.
     
    338338 *  @returns ENOENT if the packet is for another host and the routing is disabled.
    339339 */
    340 int     ip_process_packet( device_id_t device_id, packet_t packet );
     340int ip_process_packet(device_id_t device_id, packet_t packet);
    341341
    342342/** Returns the packet destination address from the IP header.
     
    344344 *  @returns The packet destination address.
    345345 */
    346 in_addr_t       ip_get_destination( ip_header_ref header );
     346in_addr_t ip_get_destination(ip_header_ref header);
    347347
    348348/** Delivers the packet to the local host.
     
    361361 *  @returns Other error codes as defined for the protocol specific tl_received_msg function.
    362362 */
    363 int     ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error );
     363int ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header, services_t error);
    364364
    365365/** Prepares the ICMP notification packet.
     
    374374 *  @returns EINVAL if the ip_prepare_icmp() fails.
    375375 */
    376 int     ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header );
     376int ip_prepare_icmp_and_get_phone(services_t error, packet_t packet, ip_header_ref header);
    377377
    378378/** Returns the ICMP phone.
     
    381381 *  @returns ENOENT if the ICMP is not registered.
    382382 */
    383 int     ip_get_icmp_phone( void );
     383int ip_get_icmp_phone(void);
    384384
    385385/** Prepares the ICMP notification packet.
     
    395395 *  @returns Other error codes as defined for the packet_set_addr().
    396396 */
    397 int     ip_prepare_icmp( packet_t packet, ip_header_ref header );
     397int ip_prepare_icmp(packet_t packet, ip_header_ref header);
    398398
    399399/** Releases the packet and returns the result.
     
    402402 *  @return The result parameter.
    403403 */
    404 int     ip_release_and_return( packet_t packet, int result );
    405 
    406 int ip_initialize( async_client_conn_t client_connection ){
     404int ip_release_and_return(packet_t packet, int result);
     405
     406int ip_initialize(async_client_conn_t client_connection){
    407407        ERROR_DECLARE;
    408408
    409         fibril_rwlock_initialize( & ip_globals.lock );
    410         fibril_rwlock_write_lock( & ip_globals.lock );
    411         fibril_rwlock_initialize( & ip_globals.protos_lock );
    412         fibril_rwlock_initialize( & ip_globals.netifs_lock );
     409        fibril_rwlock_initialize(&ip_globals.lock);
     410        fibril_rwlock_write_lock(&ip_globals.lock);
     411        fibril_rwlock_initialize(&ip_globals.protos_lock);
     412        fibril_rwlock_initialize(&ip_globals.netifs_lock);
    413413        ip_globals.packet_counter = 0;
    414414        ip_globals.gateway.address.s_addr = 0;
     
    416416        ip_globals.gateway.gateway.s_addr = 0;
    417417        ip_globals.gateway.netif = NULL;
    418         ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
    419         ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
     418        ERROR_PROPAGATE(ip_netifs_initialize(&ip_globals.netifs));
     419        ERROR_PROPAGATE(ip_protos_initialize(&ip_globals.protos));
    420420        ip_globals.client_connection = client_connection;
    421         ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
    422         ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module ));
    423         fibril_rwlock_write_unlock( & ip_globals.lock );
     421        ERROR_PROPAGATE(modules_initialize(&ip_globals.modules));
     422        ERROR_PROPAGATE(add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module));
     423        fibril_rwlock_write_unlock(&ip_globals.lock);
    424424        return EOK;
    425425}
    426426
    427 int ip_device_req( int il_phone, device_id_t device_id, services_t netif ){
     427int ip_device_req(int il_phone, device_id_t device_id, services_t netif){
    428428        ERROR_DECLARE;
    429429
    430         ip_netif_ref    ip_netif;
    431         ip_route_ref    route;
    432         int                             index;
    433         char *                  data;
    434 
    435         ip_netif = ( ip_netif_ref ) malloc( sizeof( ip_netif_t ));
    436         if( ! ip_netif ) return ENOMEM;
    437         if( ERROR_OCCURRED( ip_routes_initialize( & ip_netif->routes ))){
    438                 free( ip_netif );
     430        ip_netif_ref ip_netif;
     431        ip_route_ref route;
     432        int index;
     433        char * data;
     434
     435        ip_netif = (ip_netif_ref) malloc(sizeof(ip_netif_t));
     436        if(! ip_netif){
     437                return ENOMEM;
     438        }
     439        if(ERROR_OCCURRED(ip_routes_initialize(&ip_netif->routes))){
     440                free(ip_netif);
    439441                return ERROR_CODE;
    440442        }
     
    442444        ip_netif->service = netif;
    443445        ip_netif->state = NETIF_STOPPED;
    444         fibril_rwlock_write_lock( & ip_globals.netifs_lock );
    445         if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
    446                 fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
    447                 ip_routes_destroy( & ip_netif->routes );
    448                 free( ip_netif );
     446        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     447        if(ERROR_OCCURRED(ip_netif_initialize(ip_netif))){
     448                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
     449                ip_routes_destroy(&ip_netif->routes);
     450                free(ip_netif);
    449451                return ERROR_CODE;
    450452        }
    451         if( ip_netif->arp ) ++ ip_netif->arp->usage;
     453        if(ip_netif->arp){
     454                ++ ip_netif->arp->usage;
     455        }
    452456        // print the settings
    453         printf( "New device registered:\n\tid\t= %d\n\tphone\t= %d\n\tIPV\t= %d\n", ip_netif->device_id, ip_netif->phone, ip_netif->ipv );
    454         printf( "\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static" );
     457        printf("New device registered:\n\tid\t= %d\n\tphone\t= %d\n\tIPV\t= %d\n", ip_netif->device_id, ip_netif->phone, ip_netif->ipv);
     458        printf("\tconfiguration\t= %s\n", ip_netif->dhcp ? "dhcp" : "static");
    455459        // TODO ipv6 addresses
    456         data = ( char * ) malloc( INET_ADDRSTRLEN );
    457         if( data ){
    458                 for( index = 0; index < ip_routes_count( & ip_netif->routes ); ++ index ){
    459                         route = ip_routes_get_index( & ip_netif->routes, index );
    460                         if( route ){
    461                                 printf( "\tRouting %d:\n", index );
    462                                 inet_ntop( AF_INET, ( uint8_t * ) & route->address.s_addr, data, INET_ADDRSTRLEN );
    463                                 printf( "\t\taddress\t= %s\n", data );
    464                                 inet_ntop( AF_INET, ( uint8_t * ) & route->netmask.s_addr, data, INET_ADDRSTRLEN );
    465                                 printf( "\t\tnetmask\t= %s\n", data );
    466                                 inet_ntop( AF_INET, ( uint8_t * ) & route->gateway.s_addr, data, INET_ADDRSTRLEN );
    467                                 printf( "\t\tgateway\t= %s\n", data );
    468                         }
    469                 }
    470                 inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN );
    471                 printf( "\t\tbroadcast\t= %s\n", data );
    472                 free( data );
    473         }
    474         fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     460        data = (char *) malloc(INET_ADDRSTRLEN);
     461        if(data){
     462                for(index = 0; index < ip_routes_count(&ip_netif->routes); ++ index){
     463                        route = ip_routes_get_index(&ip_netif->routes, index);
     464                        if(route){
     465                                printf("\tRouting %d:\n", index);
     466                                inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, data, INET_ADDRSTRLEN);
     467                                printf("\t\taddress\t= %s\n", data);
     468                                inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, data, INET_ADDRSTRLEN);
     469                                printf("\t\tnetmask\t= %s\n", data);
     470                                inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, data, INET_ADDRSTRLEN);
     471                                printf("\t\tgateway\t= %s\n", data);
     472                        }
     473                }
     474                inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, data, INET_ADDRSTRLEN);
     475                printf("\t\tbroadcast\t= %s\n", data);
     476                free(data);
     477        }
     478        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    475479        return EOK;
    476480}
    477481
    478 int ip_netif_initialize( ip_netif_ref ip_netif ){
     482int ip_netif_initialize(ip_netif_ref ip_netif){
    479483        ERROR_DECLARE;
    480484
    481         measured_string_t       names[] = {{ str_dup("IPV"), 3 }, { str_dup("IP_CONFIG"), 9 }, { str_dup("IP_ADDR"), 7 }, { str_dup("IP_NETMASK"), 10 }, { str_dup("IP_GATEWAY"), 10 }, { str_dup("IP_BROADCAST"), 12 }, { str_dup("ARP"), 3 }, { str_dup("IP_ROUTING"), 10 }};
    482         measured_string_ref     configuration;
    483         size_t                          count = sizeof( names ) / sizeof( measured_string_t );
    484         char *                          data;
    485         measured_string_t       address;
    486         int                                     index;
    487         ip_route_ref            route;
    488         in_addr_t                       gateway;
     485        measured_string_t names[] = {{str_dup("IPV"), 3}, {str_dup("IP_CONFIG"), 9}, {str_dup("IP_ADDR"), 7}, {str_dup("IP_NETMASK"), 10}, {str_dup("IP_GATEWAY"), 10}, {str_dup("IP_BROADCAST"), 12}, {str_dup("ARP"), 3}, {str_dup("IP_ROUTING"), 10}};
     486        measured_string_ref configuration;
     487        size_t count = sizeof(names) / sizeof(measured_string_t);
     488        char * data;
     489        measured_string_t address;
     490        int index;
     491        ip_route_ref route;
     492        in_addr_t gateway;
    489493
    490494        ip_netif->arp = NULL;
     
    493497        ip_netif->dhcp = false;
    494498        ip_netif->routing = NET_DEFAULT_IP_ROUTING;
    495         configuration = & names[ 0 ];
     499        configuration = &names[0];
    496500        // get configuration
    497         ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data ));
    498         if( configuration ){
    499                 if( configuration[ 0 ].value ){
    500                         ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 );
    501                 }
    502                 ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length );
    503                 if( ip_netif->dhcp ){
     501        ERROR_PROPAGATE(net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id, &configuration, count, &data));
     502        if(configuration){
     503                if(configuration[0].value){
     504                        ip_netif->ipv = strtol(configuration[0].value, NULL, 0);
     505                }
     506                ip_netif->dhcp = ! str_lcmp(configuration[1].value, "dhcp", configuration[1].length);
     507                if(ip_netif->dhcp){
    504508                        // TODO dhcp
    505                         net_free_settings( configuration, data );
     509                        net_free_settings(configuration, data);
    506510                        return ENOTSUP;
    507                 }else if( ip_netif->ipv == IPV4 ){
    508                         route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
    509                         if( ! route ){
    510                                 net_free_settings( configuration, data );
     511                }else if(ip_netif->ipv == IPV4){
     512                        route = (ip_route_ref) malloc(sizeof(ip_route_t));
     513                        if(! route){
     514                                net_free_settings(configuration, data);
    511515                                return ENOMEM;
    512516                        }
     
    515519                        route->gateway.s_addr = 0;
    516520                        route->netif = ip_netif;
    517                         index = ip_routes_add( & ip_netif->routes, route );
    518                         if( index < 0 ){
    519                                 net_free_settings( configuration, data );
    520                                 free( route );
     521                        index = ip_routes_add(&ip_netif->routes, route);
     522                        if(index < 0){
     523                                net_free_settings(configuration, data);
     524                                free(route);
    521525                                return index;
    522526                        }
    523                         if( ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 2 ].value, ( uint8_t * ) & route->address.s_addr ))
    524                         || ERROR_OCCURRED( inet_pton( AF_INET, configuration[ 3 ].value, ( uint8_t * ) & route->netmask.s_addr ))
    525                         || ( inet_pton( AF_INET, configuration[ 4 ].value, ( uint8_t * ) & gateway.s_addr ) == EINVAL )
    526                         || ( inet_pton( AF_INET, configuration[ 5 ].value, ( uint8_t * ) & ip_netif->broadcast.s_addr ) == EINVAL )){
    527                                 net_free_settings( configuration, data );
     527                        if(ERROR_OCCURRED(inet_pton(AF_INET, configuration[2].value, (uint8_t *) &route->address.s_addr))
     528                                || ERROR_OCCURRED(inet_pton(AF_INET, configuration[3].value, (uint8_t *) &route->netmask.s_addr))
     529                                || (inet_pton(AF_INET, configuration[4].value, (uint8_t *) &gateway.s_addr) == EINVAL)
     530                                || (inet_pton(AF_INET, configuration[5].value, (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL)){
     531                                net_free_settings(configuration, data);
    528532                                return EINVAL;
    529533                        }
    530534                }else{
    531535                        // TODO ipv6 in separate module
    532                         net_free_settings( configuration, data );
     536                        net_free_settings(configuration, data);
    533537                        return ENOTSUP;
    534538                }
    535                 if( configuration[ 6 ].value ){
    536                         ip_netif->arp = get_running_module( & ip_globals.modules, configuration[ 6 ].value );
    537                         if( ! ip_netif->arp ){
    538                                 printf( "Failed to start the arp %s\n", configuration[ 6 ].value );
    539                                 net_free_settings( configuration, data );
     539                if(configuration[6].value){
     540                        ip_netif->arp = get_running_module(&ip_globals.modules, configuration[6].value);
     541                        if(! ip_netif->arp){
     542                                printf("Failed to start the arp %s\n", configuration[6].value);
     543                                net_free_settings(configuration, data);
    540544                                return EINVAL;
    541545                        }
    542546                }
    543                 if( configuration[ 7 ].value ){
    544                         ip_netif->routing = ( configuration[ 7 ].value[ 0 ] == 'y' );
    545                 }
    546                 net_free_settings( configuration, data );
     547                if(configuration[7].value){
     548                        ip_netif->routing = (configuration[7].value[0] == 'y');
     549                }
     550                net_free_settings(configuration, data);
    547551        }
    548552        // binds the netif service which also initializes the device
    549         ip_netif->phone = nil_bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, ip_globals.client_connection );
    550         if( ip_netif->phone < 0 ){
    551                 printf( "Failed to contact the nil service %d\n", ip_netif->service );
     553        ip_netif->phone = nil_bind_service(ip_netif->service, (ipcarg_t) ip_netif->device_id, SERVICE_IP, ip_globals.client_connection);
     554        if(ip_netif->phone < 0){
     555                printf("Failed to contact the nil service %d\n", ip_netif->service);
    552556                return ip_netif->phone;
    553557        }
    554558        // has to be after the device netif module initialization
    555         if( ip_netif->arp ){
    556                 if( route ){
    557                         address.value = ( char * ) & route->address.s_addr;
    558                         address.length = CONVERT_SIZE( in_addr_t, char, 1 );
    559                         ERROR_PROPAGATE( arp_device_req( ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, & address ));
     559        if(ip_netif->arp){
     560                if(route){
     561                        address.value = (char *) &route->address.s_addr;
     562                        address.length = CONVERT_SIZE(in_addr_t, char, 1);
     563                        ERROR_PROPAGATE(arp_device_req(ip_netif->arp->phone, ip_netif->device_id, SERVICE_IP, ip_netif->service, &address));
    560564                }else{
    561565                        ip_netif->arp = 0;
     
    563567        }
    564568        // get packet dimensions
    565         ERROR_PROPAGATE( nil_packet_size_req( ip_netif->phone, ip_netif->device_id, & ip_netif->packet_dimension ));
    566         if( ip_netif->packet_dimension.content < IP_MIN_CONTENT ){
    567                 printf( "Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->packet_dimension.content, IP_MIN_CONTENT );
     569        ERROR_PROPAGATE(nil_packet_size_req(ip_netif->phone, ip_netif->device_id, &ip_netif->packet_dimension));
     570        if(ip_netif->packet_dimension.content < IP_MIN_CONTENT){
     571                printf("Maximum transmission unit %d bytes is too small, at least %d bytes are needed\n", ip_netif->packet_dimension.content, IP_MIN_CONTENT);
    568572                ip_netif->packet_dimension.content = IP_MIN_CONTENT;
    569573        }
    570         index = ip_netifs_add( & ip_globals.netifs, ip_netif->device_id, ip_netif );
    571         if( index < 0 ) return index;
    572         if( gateway.s_addr ){
     574        index = ip_netifs_add(&ip_globals.netifs, ip_netif->device_id, ip_netif);
     575        if(index < 0){
     576                return index;
     577        }
     578        if(gateway.s_addr){
    573579                // the default gateway
    574580                ip_globals.gateway.address.s_addr = 0;
     
    580586}
    581587
    582 int ip_mtu_changed_message( device_id_t device_id, size_t mtu ){
    583         ip_netif_ref    netif;
    584 
    585         fibril_rwlock_write_lock( & ip_globals.netifs_lock );
    586         netif = ip_netifs_find( & ip_globals.netifs, device_id );
    587         if( ! netif ){
    588                 fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     588int ip_mtu_changed_message(device_id_t device_id, size_t mtu){
     589        ip_netif_ref netif;
     590
     591        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     592        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     593        if(! netif){
     594                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    589595                return ENOENT;
    590596        }
    591597        netif->packet_dimension.content = mtu;
    592         printf( "ip - device %d changed mtu to %d\n\n", device_id, mtu );
    593         fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     598        printf("ip - device %d changed mtu to %d\n\n", device_id, mtu);
     599        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    594600        return EOK;
    595601}
    596602
    597 int ip_device_state_message( device_id_t device_id, device_state_t state ){
    598         ip_netif_ref    netif;
    599 
    600         fibril_rwlock_write_lock( & ip_globals.netifs_lock );
     603int ip_device_state_message(device_id_t device_id, device_state_t state){
     604        ip_netif_ref netif;
     605
     606        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    601607        // find the device
    602         netif = ip_netifs_find( & ip_globals.netifs, device_id );
    603         if( ! netif ){
    604                 fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     608        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     609        if(! netif){
     610                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    605611                return ENOENT;
    606612        }
    607613        netif->state = state;
    608         printf( "ip - device %d changed state to %d\n\n", device_id, state );
    609         fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     614        printf("ip - device %d changed state to %d\n\n", device_id, state);
     615        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    610616        return EOK;
    611617}
    612618
    613 int ip_connect_module( services_t service ){
     619int ip_connect_module(services_t service){
    614620        return EOK;
    615621}
    616622
    617 int ip_bind_service( services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg ){
    618         return ip_register( protocol, me, 0, received_msg );
    619 }
    620 
    621 int ip_register( int protocol, services_t service, int phone, tl_received_msg_t received_msg ){
    622         ip_proto_ref    proto;
    623         int                             index;
    624 
    625         if( !( protocol && service && (( phone > 0 ) || ( received_msg )))) return EINVAL;
    626         proto = ( ip_proto_ref ) malloc( sizeof( ip_protos_t ));
    627         if( ! proto ) return ENOMEM;
     623int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg){
     624        return ip_register(protocol, me, 0, received_msg);
     625}
     626
     627int ip_register(int protocol, services_t service, int phone, tl_received_msg_t received_msg){
     628        ip_proto_ref proto;
     629        int index;
     630
     631        if(!(protocol && service && ((phone > 0) || (received_msg)))){
     632                return EINVAL;
     633        }
     634        proto = (ip_proto_ref) malloc(sizeof(ip_protos_t));
     635        if(! proto){
     636                return ENOMEM;
     637        }
    628638        proto->protocol = protocol;
    629639        proto->service = service;
    630640        proto->phone = phone;
    631641        proto->received_msg = received_msg;
    632         fibril_rwlock_write_lock( & ip_globals.protos_lock );
    633         index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
    634         if( index < 0 ){
    635                 fibril_rwlock_write_unlock( & ip_globals.protos_lock );
    636                 free( proto );
     642        fibril_rwlock_write_lock(&ip_globals.protos_lock);
     643        index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);
     644        if(index < 0){
     645                fibril_rwlock_write_unlock(&ip_globals.protos_lock);
     646                free(proto);
    637647                return index;
    638648        }
    639         printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
    640         fibril_rwlock_write_unlock( & ip_globals.protos_lock );
     649        printf("New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone);
     650        fibril_rwlock_write_unlock(&ip_globals.protos_lock);
    641651        return EOK;
    642652}
    643653
    644 int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ){
     654int ip_send_msg(int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){
    645655        ERROR_DECLARE;
    646656
    647         int                                     addrlen;
    648         ip_netif_ref            netif;
    649         ip_route_ref            route;
    650         struct sockaddr *               addr;
    651         struct sockaddr_in *    address_in;
     657        int addrlen;
     658        ip_netif_ref netif;
     659        ip_route_ref route;
     660        struct sockaddr * addr;
     661        struct sockaddr_in * address_in;
    652662//      struct sockaddr_in6 *   address_in6;
    653         in_addr_t *                     dest;
    654         in_addr_t *                     src;
    655         int                                     phone;
     663        in_addr_t * dest;
     664        in_addr_t * src;
     665        int phone;
    656666
    657667        // addresses in the host byte order
    658668        // should be the next hop address or the target destination address
    659         addrlen = packet_get_addr( packet, NULL, ( uint8_t ** ) & addr );
    660         if( addrlen < 0 ){
    661                 return ip_release_and_return( packet, addrlen );
    662         }
    663         if(( size_t ) addrlen < sizeof( struct sockaddr )){
    664                 return ip_release_and_return( packet, EINVAL );
    665         }
    666         switch( addr->sa_family ){
     669        addrlen = packet_get_addr(packet, NULL, (uint8_t **) &addr);
     670        if(addrlen < 0){
     671                return ip_release_and_return(packet, addrlen);
     672        }
     673        if((size_t) addrlen < sizeof(struct sockaddr)){
     674                return ip_release_and_return(packet, EINVAL);
     675        }
     676        switch(addr->sa_family){
    667677                case AF_INET:
    668                         if( addrlen != sizeof( struct sockaddr_in )){
    669                                 return ip_release_and_return( packet, EINVAL );
    670                         }
    671                         address_in = ( struct sockaddr_in * ) addr;
    672                         dest = & address_in->sin_addr;
    673                         if( ! dest->s_addr ){
     678                        if(addrlen != sizeof(struct sockaddr_in)){
     679                                return ip_release_and_return(packet, EINVAL);
     680                        }
     681                        address_in = (struct sockaddr_in *) addr;
     682                        dest = &address_in->sin_addr;
     683                        if(! dest->s_addr){
    674684                                dest->s_addr = IPV4_LOCALHOST_ADDRESS;
    675685                        }
     
    677687                // TODO IPv6
    678688/*              case AF_INET6:
    679                         if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
    680                         address_in6 = ( struct sockaddr_in6 * ) dest;
     689                        if(addrlen != sizeof(struct sockaddr_in6)){
     690                                return EINVAL;
     691                        }
     692                        address_in6 = (struct sockaddr_in6 *) dest;
    681693                        address_in6.sin6_addr.s6_addr;
    682694                        IPV6_LOCALHOST_ADDRESS;
    683695*/              default:
    684                         return ip_release_and_return( packet, EAFNOSUPPORT );
    685         }
    686         fibril_rwlock_read_lock( & ip_globals.netifs_lock );
     696                        return ip_release_and_return(packet, EAFNOSUPPORT);
     697        }
     698        netif = NULL;
     699        route = NULL;
     700        fibril_rwlock_read_lock(&ip_globals.netifs_lock);
    687701        // device specified?
    688         if( device_id > 0 ){
    689                 netif = ip_netifs_find( & ip_globals.netifs, device_id );
    690                 route = ip_netif_find_route( netif, * dest );
    691                 if( netif && ( ! route ) && ( ip_globals.gateway.netif == netif )){
    692                         route = & ip_globals.gateway;
    693                 }
    694         }else{
    695                 route = ip_find_route( * dest );
     702        if(device_id > 0){
     703                netif = ip_netifs_find(&ip_globals.netifs, device_id);
     704                route = ip_netif_find_route(netif, * dest);
     705                if(netif && (! route) && (ip_globals.gateway.netif == netif)){
     706                        route = &ip_globals.gateway;
     707                }
     708        }
     709        if(! route){
     710                route = ip_find_route(*dest);
    696711                netif = route ? route->netif : NULL;
    697712        }
    698         if( !( netif && route )){
    699                 fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
    700                 phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
    701                 if( phone >= 0 ){
     713        if(!(netif && route)){
     714                fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
     715                phone = ip_prepare_icmp_and_get_phone(error, packet, NULL);
     716                if(phone >= 0){
    702717                        // unreachable ICMP if no routing
    703                         icmp_destination_unreachable_msg( phone, ICMP_NET_UNREACH, 0, packet );
     718                        icmp_destination_unreachable_msg(phone, ICMP_NET_UNREACH, 0, packet);
    704719                }
    705720                return ENOENT;
    706721        }
    707         if( error ){
     722        if(error){
    708723                // do not send for broadcast, anycast packets or network broadcast
    709                 if(( ! dest->s_addr )
    710                 || ( !( ~ dest->s_addr ))
    711                 || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr )))
    712                 || ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){
    713                         return ip_release_and_return( packet, EINVAL );
    714                 }
    715         }
    716         if( route->address.s_addr == dest->s_addr ){
     724                if((! dest->s_addr)
     725                        || (!(~ dest->s_addr))
     726                        || (!(~((dest->s_addr &(~ route->netmask.s_addr)) | route->netmask.s_addr)))
     727                        || (!(dest->s_addr &(~ route->netmask.s_addr)))){
     728                        return ip_release_and_return(packet, EINVAL);
     729                }
     730        }
     731        // if the local host is the destination
     732        if((route->address.s_addr == dest->s_addr)
     733                && (dest->s_addr != IPV4_LOCALHOST_ADDRESS)){
    717734                // find the loopback device to deliver
    718735                dest->s_addr = IPV4_LOCALHOST_ADDRESS;
    719                 route = ip_find_route( * dest );
     736                route = ip_find_route(*dest);
    720737                netif = route ? route->netif : NULL;
    721                 if( !( netif && route )){
    722                         fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
    723                         phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
    724                         if( phone >= 0 ){
     738                if(!(netif && route)){
     739                        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
     740                        phone = ip_prepare_icmp_and_get_phone(error, packet, NULL);
     741                        if(phone >= 0){
    725742                                // unreachable ICMP if no routing
    726                                 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
     743                                icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet);
    727744                        }
    728745                        return ENOENT;
    729746                }
    730747        }
    731         src = ip_netif_address( netif );
    732         if( ! src ){
    733                 fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
    734                 return ip_release_and_return( packet, ENOENT );
    735         }
    736         ERROR_CODE = ip_send_route( packet, netif, route, src, * dest, error );
    737         fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
     748        src = ip_netif_address(netif);
     749        if(! src){
     750                fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
     751                return ip_release_and_return(packet, ENOENT);
     752        }
     753        ERROR_CODE = ip_send_route(packet, netif, route, src, * dest, error);
     754        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    738755        return ERROR_CODE;
    739756}
    740757
    741 in_addr_t * ip_netif_address( ip_netif_ref netif ){
    742         ip_route_ref    route;
    743 
    744         route = ip_routes_get_index( & netif->routes, 0 );
    745         return route ? & route->address : NULL;
    746 }
    747 
    748 int ip_send_route( packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error ){
     758in_addr_t * ip_netif_address(ip_netif_ref netif){
     759        ip_route_ref route;
     760
     761        route = ip_routes_get_index(&netif->routes, 0);
     762        return route ? &route->address : NULL;
     763}
     764
     765int ip_send_route(packet_t packet, ip_netif_ref netif, ip_route_ref route, in_addr_t * src, in_addr_t dest, services_t error){
    749766        ERROR_DECLARE;
    750767
    751         measured_string_t       destination;
    752         measured_string_ref     translation;
    753         char *                          data;
    754         int                                     phone;
     768        measured_string_t destination;
     769        measured_string_ref translation;
     770        char * data;
     771        int phone;
    755772
    756773        // get destination hardware address
    757         if( netif->arp && ( route->address.s_addr != dest.s_addr )){
    758                 destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
    759                 destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
    760                 if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
    761 //                      sleep( 1 );
    762 //                      ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
    763                         pq_release( ip_globals.net_phone, packet_get_id( packet ));
     774        if(netif->arp && (route->address.s_addr != dest.s_addr)){
     775                destination.value = route->gateway.s_addr ? (char *) &route->gateway.s_addr : (char *) &dest.s_addr;
     776                destination.length = CONVERT_SIZE(dest.s_addr, char, 1);
     777                if(ERROR_OCCURRED(arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data))){
     778//                      sleep(1);
     779//                      ERROR_PROPAGATE(arp_translate_req(netif->arp->phone, netif->device_id, SERVICE_IP, &destination, &translation, &data));
     780                        pq_release(ip_globals.net_phone, packet_get_id(packet));
    764781                        return ERROR_CODE;
    765782                }
    766                 if( !( translation && translation->value )){
    767                         if( translation ){
    768                                 free( translation );
    769                                 free( data );
    770                         }
    771                         phone = ip_prepare_icmp_and_get_phone( error, packet, NULL );
    772                         if( phone >= 0 ){
     783                if(!(translation && translation->value)){
     784                        if(translation){
     785                                free(translation);
     786                                free(data);
     787                        }
     788                        phone = ip_prepare_icmp_and_get_phone(error, packet, NULL);
     789                        if(phone >= 0){
    773790                                // unreachable ICMP if no routing
    774                                 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
     791                                icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet);
    775792                        }
    776793                        return EINVAL;
    777794                }
    778795        }else translation = NULL;
    779         if( ERROR_OCCURRED( ip_prepare_packet( src, dest, packet, translation ))){
    780                 pq_release( ip_globals.net_phone, packet_get_id( packet ));
     796        if(ERROR_OCCURRED(ip_prepare_packet(src, dest, packet, translation))){
     797                pq_release(ip_globals.net_phone, packet_get_id(packet));
    781798        }else{
    782                 packet = ip_split_packet( packet, netif->packet_dimension.prefix, netif->packet_dimension.content, netif->packet_dimension.suffix, netif->packet_dimension.addr_len, error );
    783                 if( packet ){
    784                         nil_send_msg( netif->phone, netif->device_id, packet, SERVICE_IP );
    785                 }
    786         }
    787         if( translation ){
    788                 free( translation );
    789                 free( data );
     799                packet = ip_split_packet(packet, netif->packet_dimension.prefix, netif->packet_dimension.content, netif->packet_dimension.suffix, netif->packet_dimension.addr_len, error);
     800                if(packet){
     801                        nil_send_msg(netif->phone, netif->device_id, packet, SERVICE_IP);
     802                }
     803        }
     804        if(translation){
     805                free(translation);
     806                free(data);
    790807        }
    791808        return ERROR_CODE;
    792809}
    793810
    794 int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination ){
     811int ip_prepare_packet(in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination){
    795812        ERROR_DECLARE;
    796813
    797         size_t                          length;
    798         ip_header_ref           header;
    799         ip_header_ref           last_header;
    800         ip_header_ref           middle_header;
    801         packet_t                        next;
    802 
    803         length = packet_get_data_length( packet );
    804         if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
    805         header = ( ip_header_ref ) packet_get_data( packet );
    806         if( destination ){
    807                 ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
     814        size_t length;
     815        ip_header_ref header;
     816        ip_header_ref last_header;
     817        ip_header_ref middle_header;
     818        packet_t next;
     819
     820        length = packet_get_data_length(packet);
     821        if((length < sizeof(ip_header_t)) || (length > IP_MAX_CONTENT)){
     822                return EINVAL;
     823        }
     824        header = (ip_header_ref) packet_get_data(packet);
     825        if(destination){
     826                ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length)));
    808827        }else{
    809                 ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0 ));
     828                ERROR_PROPAGATE(packet_set_addr(packet, NULL, NULL, 0));
    810829        }
    811830        header->version = IPV4;
     
    813832        header->fragment_offset_low = 0;
    814833        header->header_checksum = 0;
    815         if( source ) header->source_address = source->s_addr;
     834        if(source){
     835                header->source_address = source->s_addr;
     836        }
    816837        header->destination_address = dest.s_addr;
    817         fibril_rwlock_write_lock( & ip_globals.lock );
     838        fibril_rwlock_write_lock(&ip_globals.lock);
    818839        ++ ip_globals.packet_counter;
    819         header->identification = htons( ip_globals.packet_counter );
    820         fibril_rwlock_write_unlock( & ip_globals.lock );
    821 //      length = packet_get_data_length( packet );
    822         if( pq_next( packet )){
    823                 last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header ));
    824                 if( ! last_header ) return ENOMEM;
    825                 ip_create_last_header( last_header, header );
    826                 next = pq_next( packet );
    827                 while( pq_next( next )){
    828                         middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
    829                         if( ! middle_header ) return ENOMEM;
    830                         memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
     840        header->identification = htons(ip_globals.packet_counter);
     841        fibril_rwlock_write_unlock(&ip_globals.lock);
     842//      length = packet_get_data_length(packet);
     843        if(pq_next(packet)){
     844                last_header = (ip_header_ref) malloc(IP_HEADER_LENGTH(header));
     845                if(! last_header){
     846                        return ENOMEM;
     847                }
     848                ip_create_last_header(last_header, header);
     849                next = pq_next(packet);
     850                while(pq_next(next)){
     851                        middle_header = (ip_header_ref) packet_prefix(next, IP_HEADER_LENGTH(last_header));
     852                        if(! middle_header){
     853                                return ENOMEM;
     854                        }
     855                        memcpy(middle_header, last_header, IP_HEADER_LENGTH(last_header));
    831856                        header->flags |= IPFLAG_MORE_FRAGMENTS;
    832                         middle_header->total_length = htons( packet_get_data_length( next ));
    833                         middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length );
    834                         middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length );
    835                         middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
    836                         if( destination ){
    837                                 ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
    838                         }
    839                         length += packet_get_data_length( next );
    840                         next = pq_next( next );
    841                 }
    842                 middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
    843                 if( ! middle_header ) return ENOMEM;
    844                 memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
    845                 middle_header->total_length = htons( packet_get_data_length( next ));
    846                 middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length );
    847                 middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length );
    848                 middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
    849                 if( destination ){
    850                         ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
    851                 }
    852                 length += packet_get_data_length( next );
    853                 free( last_header );
     857                        middle_header->total_length = htons(packet_get_data_length(next));
     858                        middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length);
     859                        middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(length);
     860                        middle_header->header_checksum = IP_HEADER_CHECKSUM(middle_header);
     861                        if(destination){
     862                                ERROR_PROPAGATE(packet_set_addr(next, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length)));
     863                        }
     864                        length += packet_get_data_length(next);
     865                        next = pq_next(next);
     866                }
     867                middle_header = (ip_header_ref) packet_prefix(next, IP_HEADER_LENGTH(last_header));
     868                if(! middle_header){
     869                        return ENOMEM;
     870                }
     871                memcpy(middle_header, last_header, IP_HEADER_LENGTH(last_header));
     872                middle_header->total_length = htons(packet_get_data_length(next));
     873                middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length);
     874                middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(length);
     875                middle_header->header_checksum = IP_HEADER_CHECKSUM(middle_header);
     876                if(destination){
     877                        ERROR_PROPAGATE(packet_set_addr(next, NULL, (uint8_t *) destination->value, CONVERT_SIZE(char, uint8_t, destination->length)));
     878                }
     879                length += packet_get_data_length(next);
     880                free(last_header);
    854881                header->flags |= IPFLAG_MORE_FRAGMENTS;
    855882        }
    856         header->total_length = htons( length );
     883        header->total_length = htons(length);
    857884        // unnecessary for all protocols
    858         header->header_checksum = IP_HEADER_CHECKSUM( header );
     885        header->header_checksum = IP_HEADER_CHECKSUM(header);
    859886        return EOK;
    860887}
    861888
    862 int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
     889int ip_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
    863890        ERROR_DECLARE;
    864891
    865         packet_t                                packet;
    866         struct sockaddr *               addr;
    867         size_t                                  addrlen;
    868         ip_pseudo_header_ref    header;
    869         size_t                                  headerlen;
    870 
    871         * answer_count = 0;
    872         switch( IPC_GET_METHOD( * call )){
     892        packet_t packet;
     893        struct sockaddr * addr;
     894        size_t addrlen;
     895        ip_pseudo_header_ref header;
     896        size_t headerlen;
     897
     898        *answer_count = 0;
     899        switch(IPC_GET_METHOD(*call)){
    873900                case IPC_M_PHONE_HUNGUP:
    874901                        return EOK;
    875902                case NET_IL_DEVICE:
    876                         return ip_device_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ));
     903                        return ip_device_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call));
    877904                case IPC_M_CONNECT_TO_ME:
    878                         return ip_register( IL_GET_PROTO( call ), IL_GET_SERVICE( call ), IPC_GET_PHONE( call ), NULL );
     905                        return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call), IPC_GET_PHONE(call), NULL);
    879906                case NET_IL_SEND:
    880                         ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
    881                         return ip_send_msg( 0, IPC_GET_DEVICE( call ), packet, 0, IPC_GET_ERROR( call ));
     907                        ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));
     908                        return ip_send_msg(0, IPC_GET_DEVICE(call), packet, 0, IPC_GET_ERROR(call));
    882909                case NET_IL_DEVICE_STATE:
    883                         return ip_device_state_message( IPC_GET_DEVICE( call ), IPC_GET_STATE( call ));
     910                        return ip_device_state_message(IPC_GET_DEVICE(call), IPC_GET_STATE(call));
    884911                case NET_IL_RECEIVED:
    885                         ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
    886                         return ip_receive_message( IPC_GET_DEVICE( call ), packet );
     912                        ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));
     913                        return ip_receive_message(IPC_GET_DEVICE(call), packet);
    887914                case NET_IP_RECEIVED_ERROR:
    888                         ERROR_PROPAGATE( packet_translate( ip_globals.net_phone, & packet, IPC_GET_PACKET( call )));
    889                         return ip_received_error_msg( 0, IPC_GET_DEVICE( call ), packet, IPC_GET_TARGET( call ), IPC_GET_ERROR( call ));
     915                        ERROR_PROPAGATE(packet_translate(ip_globals.net_phone, &packet, IPC_GET_PACKET(call)));
     916                        return ip_received_error_msg(0, IPC_GET_DEVICE(call), packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));
    890917                case NET_IP_ADD_ROUTE:
    891                         return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call ));
     918                        return ip_add_route_req(0, IPC_GET_DEVICE(call), IP_GET_ADDRESS(call), IP_GET_NETMASK(call), IP_GET_GATEWAY(call));
    892919                case NET_IP_SET_GATEWAY:
    893                         return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call ));
     920                        return ip_set_gateway_req(0, IPC_GET_DEVICE(call), IP_GET_GATEWAY(call));
    894921                case NET_IP_GET_ROUTE:
    895                         ERROR_PROPAGATE( data_receive(( void ** ) & addr, & addrlen ));
    896                         ERROR_PROPAGATE( ip_get_route_req( 0, IP_GET_PROTOCOL( call ), addr, ( socklen_t ) addrlen, IPC_SET_DEVICE( answer ), & header, & headerlen ));
    897                         * IP_SET_HEADERLEN( answer ) = headerlen;
    898                         * answer_count = 2;
    899                         if( ! ERROR_OCCURRED( data_reply( & headerlen, sizeof( headerlen )))){
    900                                 ERROR_CODE = data_reply( header, headerlen );
    901                         }
    902                         free( header );
     922                        ERROR_PROPAGATE(data_receive((void **) &addr, &addrlen));
     923                        ERROR_PROPAGATE(ip_get_route_req(0, IP_GET_PROTOCOL(call), addr, (socklen_t) addrlen, IPC_SET_DEVICE(answer), &header, &headerlen));
     924                        *IP_SET_HEADERLEN(answer) = headerlen;
     925                        *answer_count = 2;
     926                        if(! ERROR_OCCURRED(data_reply(&headerlen, sizeof(headerlen)))){
     927                                ERROR_CODE = data_reply(header, headerlen);
     928                        }
     929                        free(header);
    903930                        return ERROR_CODE;
    904931                case NET_IL_PACKET_SPACE:
    905                         ERROR_PROPAGATE( ip_packet_size_message( IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer )));
    906                         * answer_count = 3;
     932                        ERROR_PROPAGATE(ip_packet_size_message(IPC_GET_DEVICE(call), IPC_SET_ADDR(answer), IPC_SET_PREFIX(answer), IPC_SET_CONTENT(answer), IPC_SET_SUFFIX(answer)));
     933                        *answer_count = 3;
    907934                        return EOK;
    908935                case NET_IL_MTU_CHANGED:
    909                         return ip_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call ));
     936                        return ip_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call));
    910937        }
    911938        return ENOTSUP;
    912939}
    913940
    914 int ip_packet_size_req( int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension ){
    915         if( ! packet_dimension ) return EBADMEM;
    916         return ip_packet_size_message( device_id, & packet_dimension->addr_len, & packet_dimension->prefix, & packet_dimension->content, & packet_dimension->suffix );
    917 }
    918 
    919 int ip_packet_size_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){
    920         ip_netif_ref    netif;
    921         int                             index;
    922 
    923         if( !( addr_len && prefix && content && suffix )) return EBADMEM;
    924         * content = IP_MAX_CONTENT - IP_PREFIX;
    925         fibril_rwlock_read_lock( & ip_globals.netifs_lock );
    926         if( device_id < 0 ){
    927                 * addr_len = IP_ADDR;
    928                 * prefix = 0;
    929                 * suffix = 0;
    930                 for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){
    931                         netif = ip_netifs_get_index( & ip_globals.netifs, index );
    932                         if( netif ){
    933                                 if( netif->packet_dimension.addr_len > * addr_len ) * addr_len = netif->packet_dimension.addr_len;
    934                                 if( netif->packet_dimension.prefix > * prefix ) * prefix = netif->packet_dimension.prefix;
    935                                 if( netif->packet_dimension.suffix > * suffix ) * suffix = netif->packet_dimension.suffix;
    936                         }
    937                 }
    938                 * prefix = * prefix + IP_PREFIX;
    939                 * suffix = * suffix + IP_SUFFIX;
     941int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){
     942        if(! packet_dimension){
     943                return EBADMEM;
     944        }
     945        return ip_packet_size_message(device_id, &packet_dimension->addr_len, &packet_dimension->prefix, &packet_dimension->content, &packet_dimension->suffix);
     946}
     947
     948int ip_packet_size_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){
     949        ip_netif_ref netif;
     950        int index;
     951
     952        if(!(addr_len && prefix && content && suffix)){
     953                return EBADMEM;
     954        }
     955        *content = IP_MAX_CONTENT - IP_PREFIX;
     956        fibril_rwlock_read_lock(&ip_globals.netifs_lock);
     957        if(device_id < 0){
     958                *addr_len = IP_ADDR;
     959                *prefix = 0;
     960                *suffix = 0;
     961                for(index = ip_netifs_count(&ip_globals.netifs) - 1; index >= 0; -- index){
     962                        netif = ip_netifs_get_index(&ip_globals.netifs, index);
     963                        if(netif){
     964                                if(netif->packet_dimension.addr_len > * addr_len){
     965                                        *addr_len = netif->packet_dimension.addr_len;
     966                                }
     967                                if(netif->packet_dimension.prefix > * prefix){
     968                                        *prefix = netif->packet_dimension.prefix;
     969                                }
     970                                if(netif->packet_dimension.suffix > * suffix){
     971                                        *suffix = netif->packet_dimension.suffix;
     972                                }
     973                        }
     974                }
     975                *prefix = * prefix + IP_PREFIX;
     976                *suffix = * suffix + IP_SUFFIX;
    940977        }else{
    941                 netif = ip_netifs_find( & ip_globals.netifs, device_id );
    942                 if( ! netif ){
    943                         fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
     978                netif = ip_netifs_find(&ip_globals.netifs, device_id);
     979                if(! netif){
     980                        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    944981                        return ENOENT;
    945982                }
    946                 * addr_len = ( netif->packet_dimension.addr_len > IP_ADDR ) ? netif->packet_dimension.addr_len : IP_ADDR;
    947                 * prefix = netif->packet_dimension.prefix + IP_PREFIX;
    948                 * suffix = netif->packet_dimension.suffix + IP_SUFFIX;
    949         }
    950         fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
     983                *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ? netif->packet_dimension.addr_len : IP_ADDR;
     984                *prefix = netif->packet_dimension.prefix + IP_PREFIX;
     985                *suffix = netif->packet_dimension.suffix + IP_SUFFIX;
     986        }
     987        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    951988        return EOK;
    952989}
    953990
    954 int ip_add_route_req( int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway ){
    955         ip_route_ref    route;
    956         ip_netif_ref    netif;
    957         int                             index;
    958 
    959         fibril_rwlock_write_lock( & ip_globals.netifs_lock );
    960         netif = ip_netifs_find( & ip_globals.netifs, device_id );
    961         if( ! netif ){
    962                 fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     991int ip_add_route_req(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){
     992        ip_route_ref route;
     993        ip_netif_ref netif;
     994        int index;
     995
     996        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     997        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     998        if(! netif){
     999                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    9631000                return ENOENT;
    9641001        }
    965         route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
    966         if( ! route ){
    967                 fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     1002        route = (ip_route_ref) malloc(sizeof(ip_route_t));
     1003        if(! route){
     1004                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    9681005                return ENOMEM;
    9691006        }
     
    9721009        route->gateway.s_addr = gateway.s_addr;
    9731010        route->netif = netif;
    974         index = ip_routes_add( & netif->routes, route );
    975         if( index < 0 ) free( route );
    976         fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     1011        index = ip_routes_add(&netif->routes, route);
     1012        if(index < 0){
     1013                free(route);
     1014        }
     1015        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    9771016        return index;
    9781017}
    9791018
    980 ip_route_ref ip_find_route( in_addr_t destination ){
    981         int                             index;
    982         ip_route_ref    route;
    983         ip_netif_ref    netif;
     1019ip_route_ref ip_find_route(in_addr_t destination){
     1020        int index;
     1021        ip_route_ref route;
     1022        ip_netif_ref netif;
    9841023
    9851024        // start with the last netif - the newest one
    986         index = ip_netifs_count( & ip_globals.netifs ) - 1;
    987         while( index >= 0 ){
    988                 netif = ip_netifs_get_index( & ip_globals.netifs, index );
    989                 if( netif && ( netif->state == NETIF_ACTIVE )){
    990                         route = ip_netif_find_route( netif, destination );
    991                         if( route ) return route;
     1025        index = ip_netifs_count(&ip_globals.netifs) - 1;
     1026        while(index >= 0){
     1027                netif = ip_netifs_get_index(&ip_globals.netifs, index);
     1028                if(netif && (netif->state == NETIF_ACTIVE)){
     1029                        route = ip_netif_find_route(netif, destination);
     1030                        if(route){
     1031                                return route;
     1032                        }
    9921033                }
    9931034                -- index;
    9941035        }
    995         return & ip_globals.gateway;
    996 }
    997 
    998 ip_route_ref ip_netif_find_route( ip_netif_ref netif, in_addr_t destination ){
    999         int                             index;
    1000         ip_route_ref    route;
    1001 
    1002         if( netif ){
     1036        return &ip_globals.gateway;
     1037}
     1038
     1039ip_route_ref ip_netif_find_route(ip_netif_ref netif, in_addr_t destination){
     1040        int index;
     1041        ip_route_ref route;
     1042
     1043        if(netif){
    10031044                // start with the first one - the direct route
    1004                 for( index = 0; index < ip_routes_count( & netif->routes ); ++ index ){
    1005                         route = ip_routes_get_index( & netif->routes, index );
    1006                         if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( destination.s_addr & route->netmask.s_addr ))){
     1045                for(index = 0; index < ip_routes_count(&netif->routes); ++ index){
     1046                        route = ip_routes_get_index(&netif->routes, index);
     1047                        if(route && ((route->address.s_addr &route->netmask.s_addr) == (destination.s_addr &route->netmask.s_addr))){
    10071048                                return route;
    10081049                        }
     
    10121053}
    10131054
    1014 int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
    1015         ip_netif_ref    netif;
    1016 
    1017         fibril_rwlock_write_lock( & ip_globals.netifs_lock );
    1018         netif = ip_netifs_find( & ip_globals.netifs, device_id );
    1019         if( ! netif ){
    1020                 fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     1055int ip_set_gateway_req(int ip_phone, device_id_t device_id, in_addr_t gateway){
     1056        ip_netif_ref netif;
     1057
     1058        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
     1059        netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1060        if(! netif){
     1061                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    10211062                return ENOENT;
    10221063        }
     
    10251066        ip_globals.gateway.gateway.s_addr = gateway.s_addr;
    10261067        ip_globals.gateway.netif = netif;
    1027         fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
     1068        fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    10281069        return EOK;
    10291070}
    10301071
    1031 packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error ){
    1032         size_t                  length;
    1033         packet_t                next;
    1034         packet_t                new_packet;
    1035         int                             result;
    1036         int                             phone;
     1072packet_t ip_split_packet(packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error){
     1073        size_t length;
     1074        packet_t next;
     1075        packet_t new_packet;
     1076        int result;
     1077        int phone;
    10371078
    10381079        next = packet;
    10391080        // check all packets
    1040         while( next ){
    1041                 length = packet_get_data_length( next );
     1081        while(next){
     1082                length = packet_get_data_length(next);
    10421083                // too long?
    1043                 if( length > content ){
    1044                         result = ip_fragment_packet( next, content, prefix, suffix, addr_len );
    1045                         if( result != EOK ){
    1046                                 new_packet = pq_detach( next );
    1047                                 if( next == packet ){
     1084                if(length > content){
     1085                        result = ip_fragment_packet(next, content, prefix, suffix, addr_len);
     1086                        if(result != EOK){
     1087                                new_packet = pq_detach(next);
     1088                                if(next == packet){
    10481089                                        // the new first packet of the queue
    10491090                                        packet = new_packet;
    10501091                                }
    10511092                                // fragmentation needed?
    1052                                 if( result == EPERM ){
    1053                                         phone = ip_prepare_icmp_and_get_phone( error, next, NULL );
    1054                                         if( phone >= 0 ){
     1093                                if(result == EPERM){
     1094                                        phone = ip_prepare_icmp_and_get_phone(error, next, NULL);
     1095                                        if(phone >= 0){
    10551096                                                // fragmentation necessary ICMP
    1056                                                 icmp_destination_unreachable_msg( phone, ICMP_FRAG_NEEDED, content, next );
     1097                                                icmp_destination_unreachable_msg(phone, ICMP_FRAG_NEEDED, content, next);
    10571098                                        }
    10581099                                }else{
    1059                                         pq_release( ip_globals.net_phone, packet_get_id( next ));
     1100                                        pq_release(ip_globals.net_phone, packet_get_id(next));
    10601101                                }
    10611102                                next = new_packet;
     
    10631104                        }
    10641105                }
    1065                 next = pq_next( next );
     1106                next = pq_next(next);
    10661107        }
    10671108        return packet;
    10681109}
    10691110
    1070 int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len ){
     1111int ip_fragment_packet(packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len){
    10711112        ERROR_DECLARE;
    10721113
    1073         packet_t                new_packet;
    1074         ip_header_ref   header;
    1075         ip_header_ref   middle_header;
    1076         ip_header_ref   last_header;
    1077         struct sockaddr *               src;
    1078         struct sockaddr *               dest;
    1079         socklen_t               addrlen;
    1080         int                             result;
    1081 
    1082         result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest );
    1083         if( result <= 0 ) return EINVAL;
    1084         addrlen = ( socklen_t ) result;
    1085         if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
     1114        packet_t new_packet;
     1115        ip_header_ref header;
     1116        ip_header_ref middle_header;
     1117        ip_header_ref last_header;
     1118        struct sockaddr * src;
     1119        struct sockaddr * dest;
     1120        socklen_t addrlen;
     1121        int result;
     1122
     1123        result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
     1124        if(result <= 0){
     1125                return EINVAL;
     1126        }
     1127        addrlen = (socklen_t) result;
     1128        if(packet_get_data_length(packet) <= sizeof(ip_header_t)){
     1129                return ENOMEM;
     1130        }
    10861131        // get header
    1087         header = ( ip_header_ref ) packet_get_data( packet );
    1088         if( ! header ) return EINVAL;
     1132        header = (ip_header_ref) packet_get_data(packet);
     1133        if(! header){
     1134                return EINVAL;
     1135        }
    10891136        // fragmentation forbidden?
    1090         if( header->flags & IPFLAG_DONT_FRAGMENT ){
     1137        if(header->flags &IPFLAG_DONT_FRAGMENT){
    10911138                return EPERM;
    10921139        }
    10931140        // create the last fragment
    1094         new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen > addr_len ) ? addrlen : addr_len ));
    1095         if( ! new_packet ) return ENOMEM;
     1141        new_packet = packet_get_4(ip_globals.net_phone, prefix, length, suffix, ((addrlen > addr_len) ? addrlen : addr_len));
     1142        if(! new_packet){
     1143                return ENOMEM;
     1144        }
    10961145        // allocate as much as originally
    1097         last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header ));
    1098         if( ! last_header ){
    1099                 return ip_release_and_return( packet, ENOMEM );
    1100         }
    1101         ip_create_last_header( last_header, header );
     1146        last_header = (ip_header_ref) packet_suffix(new_packet, IP_HEADER_LENGTH(header));
     1147        if(! last_header){
     1148                return ip_release_and_return(packet, ENOMEM);
     1149        }
     1150        ip_create_last_header(last_header, header);
    11021151        // trim the unused space
    1103         if( ERROR_OCCURRED( packet_trim( new_packet, 0, IP_HEADER_LENGTH( header ) - IP_HEADER_LENGTH( last_header )))){
    1104                 return ip_release_and_return( packet, ERROR_CODE );
     1152        if(ERROR_OCCURRED(packet_trim(new_packet, 0, IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)))){
     1153                return ip_release_and_return(packet, ERROR_CODE);
    11051154        }
    11061155        // biggest multiple of 8 lower than content
    11071156        // TODO even fragmentation?
    1108         length = length & ( ~ 0x7 );// ( content / 8 ) * 8
    1109         if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, last_header, (( IP_HEADER_DATA_LENGTH( header ) - (( length - IP_HEADER_LENGTH( header )) & ( ~ 0x7 ))) % (( length - IP_HEADER_LENGTH( last_header )) & ( ~ 0x7 ))), src, dest, addrlen ))){
    1110                 return ip_release_and_return( packet, ERROR_CODE );
     1157        length = length &(~ 0x7);// (content / 8) * 8
     1158        if(ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header, last_header, ((IP_HEADER_DATA_LENGTH(header) - ((length - IP_HEADER_LENGTH(header)) &(~ 0x7))) % ((length - IP_HEADER_LENGTH(last_header)) &(~ 0x7))), src, dest, addrlen))){
     1159                return ip_release_and_return(packet, ERROR_CODE);
    11111160        }
    11121161        // mark the first as fragmented
    11131162        header->flags |= IPFLAG_MORE_FRAGMENTS;
    11141163        // create middle framgents
    1115         while( IP_TOTAL_LENGTH( header ) > length ){
    1116                 new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen >= addr_len ) ? addrlen : addr_len ));
    1117                 if( ! new_packet ) return ENOMEM;
    1118                 middle_header = ip_create_middle_header( new_packet, last_header );
    1119                 if( ! middle_header ){
    1120                         return ip_release_and_return( packet, ENOMEM );
    1121                 }
    1122                 if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, ( length - IP_HEADER_LENGTH( middle_header )) & ( ~ 0x7 ), src, dest, addrlen ))){
    1123                         return ip_release_and_return( packet, ERROR_CODE );
     1164        while(IP_TOTAL_LENGTH(header) > length){
     1165                new_packet = packet_get_4(ip_globals.net_phone, prefix, length, suffix, ((addrlen >= addr_len) ? addrlen : addr_len));
     1166                if(! new_packet){
     1167                        return ENOMEM;
     1168                }
     1169                middle_header = ip_create_middle_header(new_packet, last_header);
     1170                if(! middle_header){
     1171                        return ip_release_and_return(packet, ENOMEM);
     1172                }
     1173                if(ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header, middle_header, (length - IP_HEADER_LENGTH(middle_header)) &(~ 0x7), src, dest, addrlen))){
     1174                        return ip_release_and_return(packet, ERROR_CODE);
    11241175                }
    11251176        }
    11261177        // finish the first fragment
    1127         header->header_checksum = IP_HEADER_CHECKSUM( header );
     1178        header->header_checksum = IP_HEADER_CHECKSUM(header);
    11281179        return EOK;
    11291180}
    11301181
    1131 int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen ){
     1182int ip_fragment_packet_data(packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, const struct sockaddr * src, const struct sockaddr * dest, socklen_t addrlen){
    11321183        ERROR_DECLARE;
    11331184
    1134         void *                  data;
    1135         size_t                  offset;
    1136 
    1137         data = packet_suffix( new_packet, length );
    1138         if( ! data ) return ENOMEM;
    1139         memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length );
    1140         ERROR_PROPAGATE( packet_trim( packet, 0, length ));
    1141         header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
    1142         new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
    1143         offset = IP_FRAGMENT_OFFSET( header ) + IP_HEADER_DATA_LENGTH( header );
    1144         new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( offset );
    1145         new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( offset );
    1146         new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
    1147         ERROR_PROPAGATE( packet_set_addr( new_packet, ( const uint8_t * ) src, ( const uint8_t * ) dest, addrlen ));
    1148         return pq_insert_after( packet, new_packet );
    1149 }
    1150 
    1151 ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){
    1152         ip_header_ref   middle;
    1153 
    1154         middle = ( ip_header_ref ) packet_suffix( packet, IP_HEADER_LENGTH( last ));
    1155         if( ! middle ) return NULL;
    1156         memcpy( middle, last, IP_HEADER_LENGTH( last ));
     1185        void * data;
     1186        size_t offset;
     1187
     1188        data = packet_suffix(new_packet, length);
     1189        if(! data){
     1190                return ENOMEM;
     1191        }
     1192        memcpy(data, ((void *) header) + IP_TOTAL_LENGTH(header) - length, length);
     1193        ERROR_PROPAGATE(packet_trim(packet, 0, length));
     1194        header->total_length = htons(IP_TOTAL_LENGTH(header) - length);
     1195        new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length);
     1196        offset = IP_FRAGMENT_OFFSET(header) + IP_HEADER_DATA_LENGTH(header);
     1197        new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset);
     1198        new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset);
     1199        new_header->header_checksum = IP_HEADER_CHECKSUM(new_header);
     1200        ERROR_PROPAGATE(packet_set_addr(new_packet, (const uint8_t *) src, (const uint8_t *) dest, addrlen));
     1201        return pq_insert_after(packet, new_packet);
     1202}
     1203
     1204ip_header_ref ip_create_middle_header(packet_t packet, ip_header_ref last){
     1205        ip_header_ref middle;
     1206
     1207        middle = (ip_header_ref) packet_suffix(packet, IP_HEADER_LENGTH(last));
     1208        if(! middle){
     1209                return NULL;
     1210        }
     1211        memcpy(middle, last, IP_HEADER_LENGTH(last));
    11571212        middle->flags |= IPFLAG_MORE_FRAGMENTS;
    11581213        return middle;
    11591214}
    11601215
    1161 void ip_create_last_header( ip_header_ref last, ip_header_ref first ){
    1162         ip_option_ref   option;
    1163         size_t                  next;
    1164         size_t                  length;
     1216void ip_create_last_header(ip_header_ref last, ip_header_ref first){
     1217        ip_option_ref option;
     1218        size_t next;
     1219        size_t length;
    11651220
    11661221        // copy first itself
    1167         memcpy( last, first, sizeof( ip_header_t ));
    1168         length = sizeof( ip_header_t );
    1169         next = sizeof( ip_header_t );
     1222        memcpy(last, first, sizeof(ip_header_t));
     1223        length = sizeof(ip_header_t);
     1224        next = sizeof(ip_header_t);
    11701225        // process all ip options
    1171         while( next < first->header_length ){
    1172                 option = ( ip_option_ref ) ((( uint8_t * ) first ) + next );
     1226        while(next < first->header_length){
     1227                option = (ip_option_ref) (((uint8_t *) first) + next);
    11731228                // skip end or noop
    1174                 if(( option->type == IPOPT_END ) || ( option->type == IPOPT_NOOP )){
     1229                if((option->type == IPOPT_END) || (option->type == IPOPT_NOOP)){
    11751230                        ++ next;
    11761231                }else{
    11771232                        // copy if said so or skip
    1178                         if( IPOPT_COPIED( option->type )){
    1179                                 memcpy((( uint8_t * ) last ) + length, (( uint8_t * ) first ) + next, option->length );
     1233                        if(IPOPT_COPIED(option->type)){
     1234                                memcpy(((uint8_t *) last) + length, ((uint8_t *) first) + next, option->length);
    11801235                                length += option->length;
    11811236                        }
     
    11851240        }
    11861241        // align 4 byte boundary
    1187         if( length % 4 ){
    1188                 bzero((( uint8_t * ) last ) + length, 4 - ( length % 4 ));
     1242        if(length % 4){
     1243                bzero(((uint8_t *) last) + length, 4 - (length % 4));
    11891244                last->header_length = length / 4 + 1;
    11901245        }else{
     
    11941249}
    11951250
    1196 int ip_receive_message( device_id_t device_id, packet_t packet ){
    1197         packet_t                next;
     1251int ip_receive_message(device_id_t device_id, packet_t packet){
     1252        packet_t next;
    11981253
    11991254        do{
    1200                 next = pq_detach( packet );
    1201                 ip_process_packet( device_id, packet );
     1255                next = pq_detach(packet);
     1256                ip_process_packet(device_id, packet);
    12021257                packet = next;
    1203         }while( packet );
     1258        }while(packet);
    12041259        return EOK;
    12051260}
    12061261
    1207 int ip_process_packet( device_id_t device_id, packet_t packet ){
     1262int ip_process_packet(device_id_t device_id, packet_t packet){
    12081263        ERROR_DECLARE;
    12091264
    1210         ip_header_ref   header;
    1211         in_addr_t               dest;
    1212         ip_route_ref    route;
    1213         int                             phone;
    1214         struct sockaddr *       addr;
    1215         struct sockaddr_in      addr_in;
     1265        ip_header_ref header;
     1266        in_addr_t dest;
     1267        ip_route_ref route;
     1268        int phone;
     1269        struct sockaddr * addr;
     1270        struct sockaddr_in addr_in;
    12161271//      struct sockaddr_in      addr_in6;
    1217         socklen_t               addrlen;
    1218 
    1219         header = ( ip_header_ref ) packet_get_data( packet );
    1220         if( ! header ){
    1221                 return ip_release_and_return( packet, ENOMEM );
     1272        socklen_t addrlen;
     1273
     1274        header = (ip_header_ref) packet_get_data(packet);
     1275        if(! header){
     1276                return ip_release_and_return(packet, ENOMEM);
    12221277        }
    12231278        // checksum
    1224         if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ) != IP_CHECKSUM_ZERO )){
    1225                 phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
    1226                 if( phone >= 0 ){
     1279        if((header->header_checksum) && (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)){
     1280                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1281                if(phone >= 0){
    12271282                        // checksum error ICMP
    1228                         icmp_parameter_problem_msg( phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->header_checksum )) - (( size_t ) (( void * ) header )), packet );
     1283                        icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->header_checksum)) - ((size_t) ((void *) header)), packet);
    12291284                }
    12301285                return EINVAL;
    12311286        }
    1232         if( header->ttl <= 1 ){
    1233                 phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
    1234                 if( phone >= 0 ){
     1287        if(header->ttl <= 1){
     1288                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1289                if(phone >= 0){
    12351290                        // ttl oxceeded ICMP
    1236                         icmp_time_exceeded_msg( phone, ICMP_EXC_TTL, packet );
     1291                        icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
    12371292                }
    12381293                return EINVAL;
    12391294        }
    12401295        // process ipopt and get destination
    1241         dest = ip_get_destination( header );
     1296        dest = ip_get_destination(header);
    12421297        // set the addrination address
    1243         switch( header->version ){
     1298        switch(header->version){
    12441299                case IPVERSION:
    1245                         addrlen = sizeof( addr_in );
    1246                         bzero( & addr_in, addrlen );
     1300                        addrlen = sizeof(addr_in);
     1301                        bzero(&addr_in, addrlen);
    12471302                        addr_in.sin_family = AF_INET;
    1248                         memcpy( & addr_in.sin_addr.s_addr, & dest, sizeof( dest ));
    1249                         addr = ( struct sockaddr * ) & addr_in;
     1303                        memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest));
     1304                        addr = (struct sockaddr *) &addr_in;
    12501305                        break;
    12511306/*              case IPv6VERSION:
    1252                         addrlen = sizeof( dest_in6 );
    1253                         bzero( & dest_in6, addrlen );
     1307                        addrlen = sizeof(dest_in6);
     1308                        bzero(&dest_in6, addrlen);
    12541309                        dest_in6.sin6_family = AF_INET6;
    1255                         memcpy( & dest_in6.sin6_addr.s6_addr, );
    1256                         dest = ( struct sockaddr * ) & dest_in;
     1310                        memcpy(&dest_in6.sin6_addr.s6_addr,);
     1311                        dest = (struct sockaddr *) &dest_in;
    12571312                        break;
    12581313*/              default:
    1259                         return ip_release_and_return( packet, EAFNOSUPPORT );
    1260         }
    1261         ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & addr, addrlen ));
    1262         route = ip_find_route( dest );
    1263         if( ! route ){
    1264                 phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
    1265                 if( phone >= 0 ){
     1314                        return ip_release_and_return(packet, EAFNOSUPPORT);
     1315        }
     1316        ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen));
     1317        route = ip_find_route(dest);
     1318        if(! route){
     1319                phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1320                if(phone >= 0){
    12661321                        // unreachable ICMP
    1267                         icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
     1322                        icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet);
    12681323                }
    12691324                return ENOENT;
    12701325        }
    1271         if( route->address.s_addr == dest.s_addr ){
     1326        if(route->address.s_addr == dest.s_addr){
    12721327                // local delivery
    1273                 return ip_deliver_local( device_id, packet, header, 0 );
     1328                return ip_deliver_local(device_id, packet, header, 0);
    12741329        }else{
    12751330                // only if routing enabled
    1276                 if( route->netif->routing ){
     1331                if(route->netif->routing){
    12771332                        -- header->ttl;
    1278                         return ip_send_route( packet, route->netif, route, NULL, dest, 0 );
     1333                        return ip_send_route(packet, route->netif, route, NULL, dest, 0);
    12791334                }else{
    1280                         phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
    1281                         if( phone >= 0 ){
     1335                        phone = ip_prepare_icmp_and_get_phone(0, packet, header);
     1336                        if(phone >= 0){
    12821337                                // unreachable ICMP if no routing
    1283                                 icmp_destination_unreachable_msg( phone, ICMP_HOST_UNREACH, 0, packet );
     1338                                icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, packet);
    12841339                        }
    12851340                        return ENOENT;
     
    12881343}
    12891344
    1290 int ip_received_error_msg( int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error ){
    1291         uint8_t *                       data;
    1292         int                                     offset;
    1293         icmp_type_t                     type;
    1294         icmp_code_t                     code;
    1295         ip_netif_ref            netif;
    1296         measured_string_t       address;
    1297         ip_route_ref            route;
    1298         ip_header_ref           header;
    1299 
    1300         switch( error ){
     1345int ip_received_error_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){
     1346        uint8_t * data;
     1347        int offset;
     1348        icmp_type_t type;
     1349        icmp_code_t code;
     1350        ip_netif_ref netif;
     1351        measured_string_t address;
     1352        ip_route_ref route;
     1353        ip_header_ref header;
     1354
     1355        switch(error){
    13011356                case SERVICE_ICMP:
    1302                         offset = icmp_client_process_packet( packet, & type, & code, NULL, NULL );
    1303                         if( offset < 0 ){
    1304                                 return ip_release_and_return( packet, ENOMEM );
    1305                         }
    1306                         data = packet_get_data( packet );
    1307                         header = ( ip_header_ref )( data + offset );
     1357                        offset = icmp_client_process_packet(packet, &type, &code, NULL, NULL);
     1358                        if(offset < 0){
     1359                                return ip_release_and_return(packet, ENOMEM);
     1360                        }
     1361                        data = packet_get_data(packet);
     1362                        header = (ip_header_ref)(data + offset);
    13081363                        // destination host unreachable?
    1309                         if(( type == ICMP_DEST_UNREACH ) && ( code == ICMP_HOST_UNREACH )){
    1310                                 fibril_rwlock_read_lock( & ip_globals.netifs_lock );
    1311                                 netif = ip_netifs_find( & ip_globals.netifs, device_id );
    1312                                 if( netif && netif->arp ){
    1313                                         route = ip_routes_get_index( & netif->routes, 0 );
     1364                        if((type == ICMP_DEST_UNREACH) && (code == ICMP_HOST_UNREACH)){
     1365                                fibril_rwlock_read_lock(&ip_globals.netifs_lock);
     1366                                netif = ip_netifs_find(&ip_globals.netifs, device_id);
     1367                                if(netif && netif->arp){
     1368                                        route = ip_routes_get_index(&netif->routes, 0);
    13141369                                        // from the same network?
    1315                                         if( route && (( route->address.s_addr & route->netmask.s_addr ) == ( header->destination_address & route->netmask.s_addr ))){
     1370                                        if(route && ((route->address.s_addr &route->netmask.s_addr) == (header->destination_address &route->netmask.s_addr))){
    13161371                                                // clear the ARP mapping if any
    1317                                                 address.value = ( char * ) & header->destination_address;
    1318                                                 address.length = CONVERT_SIZE( uint8_t, char, sizeof( header->destination_address ));
    1319                                                 arp_clear_address_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address );
     1372                                                address.value = (char *) &header->destination_address;
     1373                                                address.length = CONVERT_SIZE(uint8_t, char, sizeof(header->destination_address));
     1374                                                arp_clear_address_req(netif->arp->phone, netif->device_id, SERVICE_IP, &address);
    13201375                                        }
    13211376                                }
    1322                                 fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
     1377                                fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    13231378                        }
    13241379                        break;
    13251380                default:
    1326                         return ip_release_and_return( packet, ENOTSUP );
    1327         }
    1328         return ip_deliver_local( device_id, packet, header, error );
    1329 }
    1330 
    1331 int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ){
     1381                        return ip_release_and_return(packet, ENOTSUP);
     1382        }
     1383        return ip_deliver_local(device_id, packet, header, error);
     1384}
     1385
     1386int ip_deliver_local(device_id_t device_id, packet_t packet, ip_header_ref header, services_t error){
    13321387        ERROR_DECLARE;
    13331388
    1334         ip_proto_ref    proto;
    1335         int                             phone;
    1336         services_t              service;
    1337         tl_received_msg_t       received_msg;
    1338         struct sockaddr *       src;
    1339         struct sockaddr *       dest;
    1340         struct sockaddr_in      src_in;
    1341         struct sockaddr_in      dest_in;
     1389        ip_proto_ref proto;
     1390        int phone;
     1391        services_t service;
     1392        tl_received_msg_t received_msg;
     1393        struct sockaddr * src;
     1394        struct sockaddr * dest;
     1395        struct sockaddr_in src_in;
     1396        struct sockaddr_in dest_in;
    13421397//      struct sockaddr_in      src_in6;
    13431398//      struct sockaddr_in      dest_in6;
    1344         socklen_t               addrlen;
    1345 
    1346         if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || IP_FRAGMENT_OFFSET( header )){
     1399        socklen_t addrlen;
     1400
     1401        if((header->flags &IPFLAG_MORE_FRAGMENTS) || IP_FRAGMENT_OFFSET(header)){
    13471402                // TODO fragmented
    13481403                return ENOTSUP;
    13491404        }else{
    1350                 switch( header->version ){
     1405                switch(header->version){
    13511406                        case IPVERSION:
    1352                                 addrlen = sizeof( src_in );
    1353                                 bzero( & src_in, addrlen );
     1407                                addrlen = sizeof(src_in);
     1408                                bzero(&src_in, addrlen);
    13541409                                src_in.sin_family = AF_INET;
    1355                                 memcpy( & dest_in, & src_in, addrlen );
    1356                                 memcpy( & src_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address ));
    1357                                 memcpy( & dest_in.sin_addr.s_addr, & header->destination_address, sizeof( header->destination_address ));
    1358                                 src = ( struct sockaddr * ) & src_in;
    1359                                 dest = ( struct sockaddr * ) & dest_in;
     1410                                memcpy(&dest_in, &src_in, addrlen);
     1411                                memcpy(&src_in.sin_addr.s_addr, &header->source_address, sizeof(header->source_address));
     1412                                memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, sizeof(header->destination_address));
     1413                                src = (struct sockaddr *) &src_in;
     1414                                dest = (struct sockaddr *) &dest_in;
    13601415                                break;
    13611416/*                      case IPv6VERSION:
    1362                                 addrlen = sizeof( src_in6 );
    1363                                 bzero( & src_in6, addrlen );
     1417                                addrlen = sizeof(src_in6);
     1418                                bzero(&src_in6, addrlen);
    13641419                                src_in6.sin6_family = AF_INET6;
    1365                                 memcpy( & dest_in6, & src_in6, addrlen );
    1366                                 memcpy( & src_in6.sin6_addr.s6_addr, );
    1367                                 memcpy( & dest_in6.sin6_addr.s6_addr, );
    1368                                 src = ( struct sockaddr * ) & src_in;
    1369                                 dest = ( struct sockaddr * ) & dest_in;
     1420                                memcpy(&dest_in6, &src_in6, addrlen);
     1421                                memcpy(&src_in6.sin6_addr.s6_addr,);
     1422                                memcpy(&dest_in6.sin6_addr.s6_addr,);
     1423                                src = (struct sockaddr *) &src_in;
     1424                                dest = (struct sockaddr *) &dest_in;
    13701425                                break;
    13711426*/                      default:
    1372                                 return ip_release_and_return( packet, EAFNOSUPPORT );
    1373                 }
    1374                 if( ERROR_OCCURRED( packet_set_addr( packet, ( uint8_t * ) src, ( uint8_t * ) dest, addrlen ))){
    1375                         return ip_release_and_return( packet, ERROR_CODE );
     1427                                return ip_release_and_return(packet, EAFNOSUPPORT);
     1428                }
     1429                if(ERROR_OCCURRED(packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, addrlen))){
     1430                        return ip_release_and_return(packet, ERROR_CODE);
    13761431                }
    13771432                // trim padding if present
    1378                 if(( ! error ) && ( IP_TOTAL_LENGTH( header ) < packet_get_data_length( packet ))){
    1379                         if( ERROR_OCCURRED( packet_trim( packet, 0, packet_get_data_length( packet ) - IP_TOTAL_LENGTH( header )))){
    1380                                 return ip_release_and_return( packet, ERROR_CODE );
    1381                         }
    1382                 }
    1383                 fibril_rwlock_read_lock( & ip_globals.protos_lock );
    1384                 proto = ip_protos_find( & ip_globals.protos, header->protocol );
    1385                 if( ! proto ){
    1386                         fibril_rwlock_read_unlock( & ip_globals.protos_lock );
    1387                         phone = ip_prepare_icmp_and_get_phone( error, packet, header );
    1388                         if( phone >= 0 ){
     1433                if((! error) && (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))){
     1434                        if(ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)))){
     1435                                return ip_release_and_return(packet, ERROR_CODE);
     1436                        }
     1437                }
     1438                fibril_rwlock_read_lock(&ip_globals.protos_lock);
     1439                proto = ip_protos_find(&ip_globals.protos, header->protocol);
     1440                if(! proto){
     1441                        fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1442                        phone = ip_prepare_icmp_and_get_phone(error, packet, header);
     1443                        if(phone >= 0){
    13891444                                // unreachable ICMP
    1390                                 icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet );
     1445                                icmp_destination_unreachable_msg(phone, ICMP_PROT_UNREACH, 0, packet);
    13911446                        }
    13921447                        return ENOENT;
    13931448                }
    1394                 if( proto->received_msg ){
     1449                if(proto->received_msg){
    13951450                        service = proto->service;
    13961451                        received_msg = proto->received_msg;
    1397                         fibril_rwlock_read_unlock( & ip_globals.protos_lock );
    1398                         ERROR_CODE = received_msg( device_id, packet, service, error );
     1452                        fibril_rwlock_read_unlock(&ip_globals.protos_lock);
     1453                        ERROR_CODE = received_msg(device_id, packet, service, error);
    13991454                }else{
    1400                         ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error );
    1401                         fibril_rwlock_read_unlock( & ip_globals.protos_lock );
     1455                        ERROR_CODE = tl_received_msg(proto->phone, device_id, packet, proto->service, error);
     1456                        fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    14021457                }
    14031458                return ERROR_CODE;
     
    14051460}
    14061461
    1407 in_addr_t ip_get_destination( ip_header_ref header ){
    1408         in_addr_t       destination;
     1462in_addr_t ip_get_destination(ip_header_ref header){
     1463        in_addr_t destination;
    14091464
    14101465        // TODO search set ipopt route?
     
    14131468}
    14141469
    1415 int ip_prepare_icmp( packet_t packet, ip_header_ref header ){
    1416         packet_t        next;
    1417         struct sockaddr *       dest;
    1418         struct sockaddr_in      dest_in;
     1470int ip_prepare_icmp(packet_t packet, ip_header_ref header){
     1471        packet_t next;
     1472        struct sockaddr * dest;
     1473        struct sockaddr_in dest_in;
    14191474//      struct sockaddr_in      dest_in6;
    1420         socklen_t               addrlen;
     1475        socklen_t addrlen;
    14211476
    14221477        // detach the first packet and release the others
    1423         next = pq_detach( packet );
    1424         if( next ){
    1425                 pq_release( ip_globals.net_phone, packet_get_id( next ));
    1426         }
    1427         if( ! header ){
    1428                 if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
     1478        next = pq_detach(packet);
     1479        if(next){
     1480                pq_release(ip_globals.net_phone, packet_get_id(next));
     1481        }
     1482        if(! header){
     1483                if(packet_get_data_length(packet) <= sizeof(ip_header_t)){
     1484                        return ENOMEM;
     1485                }
    14291486                // get header
    1430                 header = ( ip_header_ref ) packet_get_data( packet );
    1431                 if( ! header ) return EINVAL;
     1487                header = (ip_header_ref) packet_get_data(packet);
     1488                if(! header){
     1489                        return EINVAL;
     1490                }
    14321491        }
    14331492        // only for the first fragment
    1434         if( IP_FRAGMENT_OFFSET( header )) return EINVAL;
     1493        if(IP_FRAGMENT_OFFSET(header)){
     1494                return EINVAL;
     1495        }
    14351496        // not for the ICMP protocol
    1436         if( header->protocol == IPPROTO_ICMP ){
     1497        if(header->protocol == IPPROTO_ICMP){
    14371498                return EPERM;
    14381499        }
    14391500        // set the destination address
    1440         switch( header->version ){
     1501        switch(header->version){
    14411502                case IPVERSION:
    1442                         addrlen = sizeof( dest_in );
    1443                         bzero( & dest_in, addrlen );
     1503                        addrlen = sizeof(dest_in);
     1504                        bzero(&dest_in, addrlen);
    14441505                        dest_in.sin_family = AF_INET;
    1445                         memcpy( & dest_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address ));
    1446                         dest = ( struct sockaddr * ) & dest_in;
     1506                        memcpy(&dest_in.sin_addr.s_addr, &header->source_address, sizeof(header->source_address));
     1507                        dest = (struct sockaddr *) &dest_in;
    14471508                        break;
    14481509/*              case IPv6VERSION:
    1449                         addrlen = sizeof( dest_in6 );
    1450                         bzero( & dest_in6, addrlen );
     1510                        addrlen = sizeof(dest_in6);
     1511                        bzero(&dest_in6, addrlen);
    14511512                        dest_in6.sin6_family = AF_INET6;
    1452                         memcpy( & dest_in6.sin6_addr.s6_addr, );
    1453                         dest = ( struct sockaddr * ) & dest_in;
     1513                        memcpy(&dest_in6.sin6_addr.s6_addr,);
     1514                        dest = (struct sockaddr *) &dest_in;
    14541515                        break;
    14551516*/              default:
    14561517                        return EAFNOSUPPORT;
    14571518        }
    1458         return packet_set_addr( packet, NULL, ( uint8_t * ) dest, addrlen );
    1459 }
    1460 
    1461 int ip_get_icmp_phone( void ){
    1462         ip_proto_ref    proto;
    1463         int                             phone;
    1464 
    1465         fibril_rwlock_read_lock( & ip_globals.protos_lock );
    1466         proto = ip_protos_find( & ip_globals.protos, IPPROTO_ICMP );
     1519        return packet_set_addr(packet, NULL, (uint8_t *) dest, addrlen);
     1520}
     1521
     1522int ip_get_icmp_phone(void){
     1523        ip_proto_ref proto;
     1524        int phone;
     1525
     1526        fibril_rwlock_read_lock(&ip_globals.protos_lock);
     1527        proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP);
    14671528        phone = proto ? proto->phone : ENOENT;
    1468         fibril_rwlock_read_unlock( & ip_globals.protos_lock );
     1529        fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    14691530        return phone;
    14701531}
    14711532
    1472 int ip_prepare_icmp_and_get_phone( services_t error, packet_t packet, ip_header_ref header ){
    1473         int     phone;
     1533int ip_prepare_icmp_and_get_phone(services_t error, packet_t packet, ip_header_ref header){
     1534        int phone;
    14741535
    14751536        phone = ip_get_icmp_phone();
    1476         if( error || ( phone < 0 ) || ip_prepare_icmp( packet, header )){
    1477                 return ip_release_and_return( packet, EINVAL );
     1537        if(error || (phone < 0) || ip_prepare_icmp(packet, header)){
     1538                return ip_release_and_return(packet, EINVAL);
    14781539        }
    14791540        return phone;
    14801541}
    14811542
    1482 int     ip_release_and_return( packet_t packet, int result ){
    1483         pq_release( ip_globals.net_phone, packet_get_id( packet ));
     1543int ip_release_and_return(packet_t packet, int result){
     1544        pq_release(ip_globals.net_phone, packet_get_id(packet));
    14841545        return result;
    14851546}
    14861547
    1487 int ip_get_route_req( int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen ){
    1488         struct sockaddr_in *    address_in;
     1548int ip_get_route_req(int ip_phone, ip_protocol_t protocol, const struct sockaddr * destination, socklen_t addrlen, device_id_t * device_id, ip_pseudo_header_ref * header, size_t * headerlen){
     1549        struct sockaddr_in * address_in;
    14891550//      struct sockaddr_in6 *   address_in6;
    1490         in_addr_t *                             dest;
    1491         in_addr_t *                             src;
    1492         ip_route_ref                    route;
    1493         ipv4_pseudo_header_ref  header_in;
    1494 
    1495         if( !( destination && ( addrlen > 0 ))) return EINVAL;
    1496         if( !( device_id && header && headerlen )) return EBADMEM;
    1497         if(( size_t ) addrlen < sizeof( struct sockaddr )){
     1551        in_addr_t * dest;
     1552        in_addr_t * src;
     1553        ip_route_ref route;
     1554        ipv4_pseudo_header_ref header_in;
     1555
     1556        if(!(destination && (addrlen > 0))){
    14981557                return EINVAL;
    14991558        }
    1500         switch( destination->sa_family ){
     1559        if(!(device_id && header && headerlen)){
     1560                return EBADMEM;
     1561        }
     1562        if((size_t) addrlen < sizeof(struct sockaddr)){
     1563                return EINVAL;
     1564        }
     1565        switch(destination->sa_family){
    15011566                case AF_INET:
    1502                         if( addrlen != sizeof( struct sockaddr_in )){
     1567                        if(addrlen != sizeof(struct sockaddr_in)){
    15031568                                return EINVAL;
    15041569                        }
    1505                         address_in = ( struct sockaddr_in * ) destination;
    1506                         dest = & address_in->sin_addr;
    1507                         if( ! dest->s_addr ){
     1570                        address_in = (struct sockaddr_in *) destination;
     1571                        dest = &address_in->sin_addr;
     1572                        if(! dest->s_addr){
    15081573                                dest->s_addr = IPV4_LOCALHOST_ADDRESS;
    15091574                        }
     
    15111576                // TODO IPv6
    15121577/*              case AF_INET6:
    1513                         if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
    1514                         address_in6 = ( struct sockaddr_in6 * ) dest;
     1578                        if(addrlen != sizeof(struct sockaddr_in6)){
     1579                                return EINVAL;
     1580                        }
     1581                        address_in6 = (struct sockaddr_in6 *) dest;
    15151582                        address_in6.sin6_addr.s6_addr;
    15161583*/              default:
    15171584                        return EAFNOSUPPORT;
    15181585        }
    1519         fibril_rwlock_read_lock( & ip_globals.lock );
    1520         route = ip_find_route( * dest );
    1521         if( !( route && route->netif )){
    1522                 fibril_rwlock_read_unlock( & ip_globals.lock );
     1586        fibril_rwlock_read_lock(&ip_globals.lock);
     1587        route = ip_find_route(*dest);
     1588        // if the local host is the destination
     1589        if(route && (route->address.s_addr == dest->s_addr)
     1590                && (dest->s_addr != IPV4_LOCALHOST_ADDRESS)){
     1591                // find the loopback device to deliver
     1592                dest->s_addr = IPV4_LOCALHOST_ADDRESS;
     1593                route = ip_find_route(*dest);
     1594        }
     1595        if(!(route && route->netif)){
     1596                fibril_rwlock_read_unlock(&ip_globals.lock);
    15231597                return ENOENT;
    15241598        }
    1525         * device_id = route->netif->device_id;
    1526         src = ip_netif_address( route->netif );
    1527         fibril_rwlock_read_unlock( & ip_globals.lock );
    1528         * headerlen = sizeof( * header_in );
    1529         header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen );
    1530         if( ! header_in ) return ENOMEM;
    1531         bzero( header_in, * headerlen );
     1599        *device_id = route->netif->device_id;
     1600        src = ip_netif_address(route->netif);
     1601        fibril_rwlock_read_unlock(&ip_globals.lock);
     1602        *headerlen = sizeof(*header_in);
     1603        header_in = (ipv4_pseudo_header_ref) malloc(*headerlen);
     1604        if(! header_in){
     1605                return ENOMEM;
     1606        }
     1607        bzero(header_in, * headerlen);
    15321608        header_in->destination_address = dest->s_addr;
    15331609        header_in->source_address = src->s_addr;
    15341610        header_in->protocol = protocol;
    15351611        header_in->data_length = 0;
    1536         * header = ( ip_pseudo_header_ref ) header_in;
     1612        *header = (ip_pseudo_header_ref) header_in;
    15371613        return EOK;
    15381614}
Note: See TracChangeset for help on using the changeset viewer.