Subversion Repositories HelenOS

Rev

Rev 4575 | Rev 4589 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4575 Rev 4582
Line 33... Line 33...
33
/** @file
33
/** @file
34
 */
34
 */
35
 
35
 
36
#include <async.h>
36
#include <async.h>
37
#include <errno.h>
37
#include <errno.h>
38
#include <rwlock.h>
38
#include <fibril_sync.h>
39
#include <stdio.h>
39
#include <stdio.h>
40
#include <string.h>
40
#include <string.h>
41
 
41
 
42
#include <ipc/ipc.h>
42
#include <ipc/ipc.h>
43
#include <ipc/services.h>
43
#include <ipc/services.h>
Line 144... Line 144...
144
/** Initializes the module.
144
/** Initializes the module.
145
 */
145
 */
146
int ip_initialize( async_client_conn_t client_connection ){
146
int ip_initialize( async_client_conn_t client_connection ){
147
    ERROR_DECLARE;
147
    ERROR_DECLARE;
148
 
148
 
149
    rwlock_initialize( & ip_globals.lock );
149
    fibril_rwlock_initialize( & ip_globals.lock );
150
    rwlock_write_lock( & ip_globals.lock );
150
    fibril_rwlock_write_lock( & ip_globals.lock );
151
    rwlock_initialize( & ip_globals.protos_lock );
151
    fibril_rwlock_initialize( & ip_globals.protos_lock );
152
    rwlock_initialize( & ip_globals.netifs_lock );
152
    fibril_rwlock_initialize( & ip_globals.netifs_lock );
153
    ip_globals.packet_counter = 0;
153
    ip_globals.packet_counter = 0;
154
    ip_globals.gateway.address.s_addr = 0;
154
    ip_globals.gateway.address.s_addr = 0;
155
    ip_globals.gateway.netmask.s_addr = 0;
155
    ip_globals.gateway.netmask.s_addr = 0;
156
    ip_globals.gateway.gateway.s_addr = 0;
156
    ip_globals.gateway.gateway.s_addr = 0;
157
    ip_globals.gateway.netif = NULL;
157
    ip_globals.gateway.netif = NULL;
158
    ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
158
    ERROR_PROPAGATE( ip_netifs_initialize( & ip_globals.netifs ));
159
    ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
159
    ERROR_PROPAGATE( ip_protos_initialize( & ip_globals.protos ));
160
    ip_globals.client_connection = client_connection;
160
    ip_globals.client_connection = client_connection;
161
    ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
161
    ERROR_PROPAGATE( modules_initialize( & ip_globals.modules ));
162
    ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module ));
162
    ERROR_PROPAGATE( add_module( NULL, & ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module ));
163
    rwlock_write_unlock( & ip_globals.lock );
163
    fibril_rwlock_write_unlock( & ip_globals.lock );
164
    return EOK;
164
    return EOK;
165
}
165
}
166
 
166
 
167
int ip_device_req( int il_phone, device_id_t device_id, services_t netif ){
167
int ip_device_req( int il_phone, device_id_t device_id, services_t netif ){
168
    ERROR_DECLARE;
168
    ERROR_DECLARE;
Line 179... Line 179...
179
        return ERROR_CODE;
179
        return ERROR_CODE;
180
    }
180
    }
181
    ip_netif->device_id = device_id;
181
    ip_netif->device_id = device_id;
182
    ip_netif->service = netif;
182
    ip_netif->service = netif;
183
    ip_netif->state = NETIF_STOPPED;
183
    ip_netif->state = NETIF_STOPPED;
184
    rwlock_write_lock( & ip_globals.netifs_lock );
184
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
185
    if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
185
    if( ERROR_OCCURRED( ip_netif_initialize( ip_netif ))){
186
        rwlock_write_unlock( & ip_globals.netifs_lock );
186
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
187
        ip_routes_destroy( & ip_netif->routes );
187
        ip_routes_destroy( & ip_netif->routes );
188
        free( ip_netif );
188
        free( ip_netif );
189
        return ERROR_CODE;
189
        return ERROR_CODE;
190
    }
190
    }
191
    if( ip_netif->arp ) ++ ip_netif->arp->usage;
191
    if( ip_netif->arp ) ++ ip_netif->arp->usage;
Line 213... Line 213...
213
        printf( "\tdns1\t= %s\n", data );
213
        printf( "\tdns1\t= %s\n", data );
214
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns2, data, INET_ADDRSTRLEN );
214
        inet_ntop( AF_INET, ( uint8_t * ) & ip_netif->dns2, data, INET_ADDRSTRLEN );
215
        printf( "\tdns2\t= %s\n", data );
215
        printf( "\tdns2\t= %s\n", data );
216
        free( data );
216
        free( data );
217
    }
217
    }
218
    rwlock_write_unlock( & ip_globals.netifs_lock );
218
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
219
    return EOK;
219
    return EOK;
220
}
220
}
221
 
221
 
222
int ip_netif_initialize( ip_netif_ref ip_netif ){
222
int ip_netif_initialize( ip_netif_ref ip_netif ){
223
    ERROR_DECLARE;
223
    ERROR_DECLARE;
Line 331... Line 331...
331
/*  packet_t        packet;
331
/*  packet_t        packet;
332
    in_addr_t       destination;
332
    in_addr_t       destination;
333
*/
333
*/
334
    ip_netif_ref    netif;
334
    ip_netif_ref    netif;
335
 
335
 
336
    rwlock_write_lock( & ip_globals.netifs_lock );
336
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
337
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
337
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
338
    if( ! netif ){
338
    if( ! netif ){
339
        rwlock_write_unlock( & ip_globals.netifs_lock );
339
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
340
        return ENOENT;
340
        return ENOENT;
341
    }
341
    }
342
    netif->state = state;
342
    netif->state = state;
343
    // TODO state
343
    // TODO state
344
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
344
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
345
    rwlock_write_unlock( & ip_globals.netifs_lock );
345
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
346
//  if( netif->arp ){
346
//  if( netif->arp ){
347
/*      address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
347
/*      address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
348
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
348
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
349
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
349
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
350
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
350
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
Line 404... Line 404...
404
    if( ! proto ) return ENOMEM;
404
    if( ! proto ) return ENOMEM;
405
    proto->protocol = protocol;
405
    proto->protocol = protocol;
406
    proto->service = service;
406
    proto->service = service;
407
    proto->phone = phone;
407
    proto->phone = phone;
408
    proto->received_msg = received_msg;
408
    proto->received_msg = received_msg;
409
    rwlock_write_lock( & ip_globals.protos_lock );
409
    fibril_rwlock_write_lock( & ip_globals.protos_lock );
410
    index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
410
    index = ip_protos_add( & ip_globals.protos, proto->protocol, proto );
411
    if( index < 0 ){
411
    if( index < 0 ){
412
        rwlock_write_unlock( & ip_globals.protos_lock );
412
        fibril_rwlock_write_unlock( & ip_globals.protos_lock );
413
        free( proto );
413
        free( proto );
414
        return index;
414
        return index;
415
    }
415
    }
416
    printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
416
    printf( "New protocol registered:\n\tprotocol\t= %d\n\tphone\t= %d\n", proto->protocol, proto->phone );
417
    rwlock_write_unlock( & ip_globals.protos_lock );
417
    fibril_rwlock_write_unlock( & ip_globals.protos_lock );
418
    return EOK;
418
    return EOK;
419
}
419
}
420
 
420
 
421
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender ){
421
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender ){
422
    ERROR_DECLARE;
422
    ERROR_DECLARE;
Line 437... Line 437...
437
    // TODO IPv6
437
    // TODO IPv6
438
    if( length != IP_ADDR ){
438
    if( length != IP_ADDR ){
439
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
439
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
440
        return EINVAL;
440
        return EINVAL;
441
    }
441
    }
442
    rwlock_read_lock( & ip_globals.netifs_lock );
442
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
443
    // device specified?
443
    // device specified?
444
//  dest.s_addr = ntohl( dest.s_addr );
444
//  dest.s_addr = ntohl( dest.s_addr );
445
    if( device_id > 0 ){
445
    if( device_id > 0 ){
446
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
446
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
447
        route = ip_netif_find_route( netif, * dest );
447
        route = ip_netif_find_route( netif, * dest );
Line 449... Line 449...
449
        // TODO IPv6
449
        // TODO IPv6
450
        route = ip_find_route( * dest );
450
        route = ip_find_route( * dest );
451
        netif = route ? route->netif : NULL;
451
        netif = route ? route->netif : NULL;
452
    }
452
    }
453
    if( !( netif && route )){
453
    if( !( netif && route )){
454
        rwlock_read_unlock( & ip_globals.netifs_lock );
454
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
455
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
455
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
456
        return ENOENT;
456
        return ENOENT;
457
    }
457
    }
458
    // to me?
458
    // to me?
459
    if( route->address.s_addr == dest->s_addr ){
459
    if( route->address.s_addr == dest->s_addr ){
460
        // TODO loopback deliver
460
        // TODO loopback deliver
461
        rwlock_read_unlock( & ip_globals.netifs_lock );
461
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
462
        return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet ));
462
        return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet ));
463
    }
463
    }
464
 
464
 
465
    src = ip_netif_addr( netif );
465
    src = ip_netif_addr( netif );
466
    if( ! src ){
466
    if( ! src ){
467
        rwlock_read_unlock( & ip_globals.netifs_lock );
467
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
468
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
468
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
469
        return ENOENT;
469
        return ENOENT;
470
    }
470
    }
471
    if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, * dest ))){
471
    if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, * dest ))){
472
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
472
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
473
    }
473
    }
474
    rwlock_read_unlock( & ip_globals.netifs_lock );
474
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
475
    return ERROR_CODE;
475
    return ERROR_CODE;
476
}
476
}
477
 
477
 
478
in_addr_t * ip_netif_addr( ip_netif_ref netif ){
478
in_addr_t * ip_netif_addr( ip_netif_ref netif ){
479
    ip_route_ref    route;
479
    ip_route_ref    route;
Line 494... Line 494...
494
    // get destination hardware address
494
    // get destination hardware address
495
    if( netif->arp ){
495
    if( netif->arp ){
496
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
496
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
497
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
497
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
498
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
498
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
499
            usleep( 200000 );
499
            sleep( 1 );
500
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
500
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
501
        }
501
        }
502
        // TODO unreachable
502
        // TODO unreachable
503
        if( ! translation ) return EINVAL;
503
        if( ! translation ) return EINVAL;
504
        if( ! translation->value ){
504
        if( ! translation->value ){
Line 550... Line 550...
550
    header->version = 4;
550
    header->version = 4;
551
    header->total_length = htons( length );
551
    header->total_length = htons( length );
552
    header->fragment_offset = 0;
552
    header->fragment_offset = 0;
553
    if( source ) header->source_address = source->s_addr;
553
    if( source ) header->source_address = source->s_addr;
554
    header->destination_address = dest.s_addr;
554
    header->destination_address = dest.s_addr;
555
    rwlock_write_lock( & ip_globals.lock );
555
    fibril_rwlock_write_lock( & ip_globals.lock );
556
    ++ ip_globals.packet_counter;
556
    ++ ip_globals.packet_counter;
557
    header->identification = htons( ip_globals.packet_counter );
557
    header->identification = htons( ip_globals.packet_counter );
558
    rwlock_write_unlock( & ip_globals.lock );
558
    fibril_rwlock_write_unlock( & ip_globals.lock );
559
    header->header_checksum = 0;
559
    header->header_checksum = 0;
560
    // unnecessary for all protocols
560
    // unnecessary for all protocols
561
    header->header_checksum = IP_HEADER_CHECKSUM( header );
561
    header->header_checksum = IP_HEADER_CHECKSUM( header );
562
    return EOK;
562
    return EOK;
563
}
563
}
Line 601... Line 601...
601
    ip_netif_ref    netif;
601
    ip_netif_ref    netif;
602
    int             index;
602
    int             index;
603
 
603
 
604
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
604
    if( !( addr_len && prefix && content && suffix )) return EBADMEM;
605
    * content = IP_MAX_CONTENT - IP_PREFIX;
605
    * content = IP_MAX_CONTENT - IP_PREFIX;
606
    rwlock_read_lock( & ip_globals.netifs_lock );
606
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
607
    if( device_id < 0 ){
607
    if( device_id < 0 ){
608
        * addr_len = IP_ADDR;
608
        * addr_len = IP_ADDR;
609
        * prefix = 0;
609
        * prefix = 0;
610
        * suffix = 0;
610
        * suffix = 0;
611
        for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){
611
        for( index = ip_netifs_count( & ip_globals.netifs ) - 1; index >= 0; -- index ){
Line 619... Line 619...
619
        * prefix = * prefix + IP_PREFIX;
619
        * prefix = * prefix + IP_PREFIX;
620
        * suffix = * suffix + IP_SUFFIX;
620
        * suffix = * suffix + IP_SUFFIX;
621
    }else{
621
    }else{
622
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
622
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
623
        if( ! netif ){
623
        if( ! netif ){
624
            rwlock_read_unlock( & ip_globals.netifs_lock );
624
            fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
625
            return ENOENT;
625
            return ENOENT;
626
        }
626
        }
627
        * addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR;
627
        * addr_len = ( netif->addr_len > IP_ADDR ) ? netif->addr_len : IP_ADDR;
628
        * prefix = netif->prefix + IP_PREFIX;
628
        * prefix = netif->prefix + IP_PREFIX;
629
        * suffix = netif->suffix + IP_SUFFIX;
629
        * suffix = netif->suffix + IP_SUFFIX;
630
    }
630
    }
631
    rwlock_read_unlock( & ip_globals.netifs_lock );
631
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
632
    return EOK;
632
    return EOK;
633
}
633
}
634
 
634
 
635
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 ){
635
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 ){
636
    ip_route_ref    route;
636
    ip_route_ref    route;
637
    ip_netif_ref    netif;
637
    ip_netif_ref    netif;
638
    int             index;
638
    int             index;
639
 
639
 
640
    rwlock_write_lock( & ip_globals.netifs_lock );
640
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
641
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
641
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
642
    if( ! netif ){
642
    if( ! netif ){
643
        rwlock_write_unlock( & ip_globals.netifs_lock );
643
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
644
        return ENOENT;
644
        return ENOENT;
645
    }
645
    }
646
    route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
646
    route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
647
    if( ! route ){
647
    if( ! route ){
648
        rwlock_write_unlock( & ip_globals.netifs_lock );
648
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
649
        return ENOMEM;
649
        return ENOMEM;
650
    }
650
    }
651
    route->address.s_addr = address.s_addr;
651
    route->address.s_addr = address.s_addr;
652
    route->netmask.s_addr = netmask.s_addr;
652
    route->netmask.s_addr = netmask.s_addr;
653
    route->gateway.s_addr = gateway.s_addr;
653
    route->gateway.s_addr = gateway.s_addr;
654
    route->netif = netif;
654
    route->netif = netif;
655
    index = ip_routes_add( & netif->routes, route );
655
    index = ip_routes_add( & netif->routes, route );
656
    if( index < 0 ) free( route );
656
    if( index < 0 ) free( route );
657
    rwlock_write_unlock( & ip_globals.netifs_lock );
657
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
658
    return index;
658
    return index;
659
}
659
}
660
 
660
 
661
ip_route_ref ip_find_route( in_addr_t destination ){
661
ip_route_ref ip_find_route( in_addr_t destination ){
662
    int             index;
662
    int             index;
Line 693... Line 693...
693
}
693
}
694
 
694
 
695
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
695
int ip_set_gateway_req( int ip_phone, device_id_t device_id, in_addr_t gateway ){
696
    ip_netif_ref    netif;
696
    ip_netif_ref    netif;
697
 
697
 
698
    rwlock_write_lock( & ip_globals.netifs_lock );
698
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
699
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
699
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
700
    if( ! netif ){
700
    if( ! netif ){
701
        rwlock_write_unlock( & ip_globals.netifs_lock );
701
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
702
        return ENOENT;
702
        return ENOENT;
703
    }
703
    }
704
    ip_globals.gateway.address.s_addr = 0;
704
    ip_globals.gateway.address.s_addr = 0;
705
    ip_globals.gateway.netmask.s_addr = 0;
705
    ip_globals.gateway.netmask.s_addr = 0;
706
    ip_globals.gateway.gateway.s_addr = gateway.s_addr;
706
    ip_globals.gateway.gateway.s_addr = gateway.s_addr;
707
    ip_globals.gateway.netif = netif;
707
    ip_globals.gateway.netif = netif;
708
    rwlock_write_unlock( & ip_globals.netifs_lock );
708
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
709
    return EOK;
709
    return EOK;
710
}
710
}
711
 
711
 
712
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len ){
712
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len ){
713
    size_t          length;
713
    size_t          length;
Line 913... Line 913...
913
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
913
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
914
        // TODO fragmented
914
        // TODO fragmented
915
        return ENOTSUP;
915
        return ENOTSUP;
916
    }else{
916
    }else{
917
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR ));
917
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR ));
918
        rwlock_read_lock( & ip_globals.protos_lock );
918
        fibril_rwlock_read_lock( & ip_globals.protos_lock );
919
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
919
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
920
        if( ! proto ){
920
        if( ! proto ){
921
            rwlock_read_unlock( & ip_globals.protos_lock );
921
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
922
            return ENOENT;
922
            return ENOENT;
923
        }
923
        }
924
        if( proto->received_msg ){
924
        if( proto->received_msg ){
925
            ERROR_CODE = proto->received_msg( device_id, packet, SERVICE_IP );
925
            ERROR_CODE = proto->received_msg( device_id, packet, SERVICE_IP );
926
        }else{
926
        }else{
927
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service );
927
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service );
928
        }
928
        }
929
        rwlock_read_unlock( & ip_globals.protos_lock );
929
        fibril_rwlock_read_unlock( & ip_globals.protos_lock );
930
        return ERROR_CODE;
930
        return ERROR_CODE;
931
    }
931
    }
932
}
932
}
933
 
933
 
934
in_addr_t ip_get_destination( ip_header_ref header ){
934
in_addr_t ip_get_destination( ip_header_ref header ){