Subversion Repositories HelenOS

Rev

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

Rev 4720 Rev 4722
Line 80... Line 80...
80
#include "ip.h"
80
#include "ip.h"
81
#include "ip_header.h"
81
#include "ip_header.h"
82
#include "ip_messages.h"
82
#include "ip_messages.h"
83
#include "ip_module.h"
83
#include "ip_module.h"
84
 
84
 
85
/** Default IP version.
85
/** IP version 4.
86
 */
86
 */
-
 
87
#define IPV4                4
-
 
88
 
-
 
89
/** Default network interface IP version.
-
 
90
 */
87
#define DEFAULT_IPV     4
91
#define NET_DEFAULT_IPV     IPV4
-
 
92
 
-
 
93
/** Default network interface IP routing.
-
 
94
 */
-
 
95
#define NET_DEFAULT_IP_ROUTING  false
88
 
96
 
89
/** Minimum IP packet content.
97
/** Minimum IP packet content.
90
 */
98
 */
91
#define IP_MIN_CONTENT  576
99
#define IP_MIN_CONTENT  576
92
 
100
 
Line 132... Line 140...
132
/** Returns the IP packet header checksum.
140
/** Returns the IP packet header checksum.
133
 *  @param header The IP packet header. Input parameter.
141
 *  @param header The IP packet header. Input parameter.
134
 */
142
 */
135
#define IP_HEADER_CHECKSUM( header )    ( htons( ip_checksum(( uint8_t * )( header ), IP_HEADER_LENGTH( header ))))
143
#define IP_HEADER_CHECKSUM( header )    ( htons( ip_checksum(( uint8_t * )( header ), IP_HEADER_LENGTH( header ))))
136
 
144
 
-
 
145
/** Returns the fragment offest.
-
 
146
 *  @param length The prefixed data total length. Input parameter.
-
 
147
 */
-
 
148
#define IP_FRAGMENT_OFFSET( length ) (( length ) / 8 )
-
 
149
 
137
/** IP global data.
150
/** IP global data.
138
 */
151
 */
139
ip_globals_t    ip_globals;
152
ip_globals_t    ip_globals;
140
 
153
 
141
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
154
DEVICE_MAP_IMPLEMENT( ip_netifs, ip_netif_t )
Line 302... Line 315...
302
    ip_route_ref        route;
315
    ip_route_ref        route;
303
    in_addr_t           gateway;
316
    in_addr_t           gateway;
304
 
317
 
305
    ip_netif->arp = NULL;
318
    ip_netif->arp = NULL;
306
    route = NULL;
319
    route = NULL;
-
 
320
    ip_netif->ipv = NET_DEFAULT_IPV;
-
 
321
    ip_netif->dhcp = false;
-
 
322
    ip_netif->routing = NET_DEFAULT_IP_ROUTING;
307
    configuration = & names[ 0 ];
323
    configuration = & names[ 0 ];
308
    // get configuration
324
    // get configuration
309
    ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data ));
325
    ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data ));
310
    if( configuration ){
326
    if( configuration ){
311
        if( configuration[ 0 ].value ){
327
        if( configuration[ 0 ].value ){
312
            ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 );
328
            ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 );
313
        }else{
-
 
314
            ip_netif->ipv = DEFAULT_IPV;
-
 
315
        }
329
        }
316
        ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length );
330
        ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length );
317
        if( ip_netif->dhcp ){
331
        if( ip_netif->dhcp ){
318
            // TODO dhcp
332
            // TODO dhcp
319
            net_free_settings( configuration, data );
333
            net_free_settings( configuration, data );
320
            return ENOTSUP;
334
            return ENOTSUP;
321
        }else if( ip_netif->ipv == 4 ){
335
        }else if( ip_netif->ipv == IPV4 ){
322
            route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
336
            route = ( ip_route_ref ) malloc( sizeof( ip_route_t ));
323
            if( ! route ){
337
            if( ! route ){
324
                net_free_settings( configuration, data );
338
                net_free_settings( configuration, data );
325
                return ENOMEM;
339
                return ENOMEM;
326
            }
340
            }
Line 353... Line 367...
353
            if( ! ip_netif->arp ){
367
            if( ! ip_netif->arp ){
354
                printf( "Failed to start the arp %s\n", configuration[ 8 ].value );
368
                printf( "Failed to start the arp %s\n", configuration[ 8 ].value );
355
                net_free_settings( configuration, data );
369
                net_free_settings( configuration, data );
356
                return EINVAL;
370
                return EINVAL;
357
            }
371
            }
358
        }else{
-
 
359
            ip_netif->arp = NULL;
-
 
360
        }
372
        }
-
 
373
        if( configuration[ 9 ].value ){
361
        ip_netif->routing = configuration[ 9 ].value && ( configuration[ 9 ].value[ 0 ] == 'y' );
374
            ip_netif->routing = ( configuration[ 9 ].value[ 0 ] == 'y' );
-
 
375
        }
362
        net_free_settings( configuration, data );
376
        net_free_settings( configuration, data );
363
    }
377
    }
364
    // binds the netif service which also initializes the device
378
    // binds the netif service which also initializes the device
365
    ip_netif->phone = bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection );
379
    ip_netif->phone = bind_service( ip_netif->service, ( ipcarg_t ) ip_netif->device_id, SERVICE_IP, 0, ip_globals.client_connection );
366
    if( ip_netif->phone < 0 ){
380
    if( ip_netif->phone < 0 ){
Line 596... Line 610...
596
    measured_string_ref translation;
610
    measured_string_ref translation;
597
    char *              data;
611
    char *              data;
598
    int                 phone;
612
    int                 phone;
599
 
613
 
600
    // get destination hardware address
614
    // get destination hardware address
601
    if( netif->arp ){
615
    if( netif->arp && ( route->address.s_addr != dest.s_addr )){
602
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
616
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
603
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
617
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
604
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
618
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
605
//          sleep( 1 );
619
//          sleep( 1 );
606
//          ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
620
//          ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
Line 647... Line 661...
647
    length = packet_get_data_length( packet );
661
    length = packet_get_data_length( packet );
648
    if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
662
    if(( length < sizeof( ip_header_t )) || ( length > IP_MAX_CONTENT )) return EINVAL;
649
    header = ( ip_header_ref ) packet_get_data( packet );
663
    header = ( ip_header_ref ) packet_get_data( packet );
650
    if( destination ){
664
    if( destination ){
651
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
665
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
-
 
666
    }else{
-
 
667
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0 ));
652
    }
668
    }
653
    header->version = 4;
669
    header->version = IPV4;
654
    header->fragment_offset = 0;
670
    header->fragment_offset = 0;
655
    header->header_checksum = 0;
671
    header->header_checksum = 0;
656
    if( source ) header->source_address = source->s_addr;
672
    if( source ) header->source_address = source->s_addr;
657
    header->destination_address = dest.s_addr;
673
    header->destination_address = dest.s_addr;
658
    fibril_rwlock_write_lock( & ip_globals.lock );
674
    fibril_rwlock_write_lock( & ip_globals.lock );
Line 669... Line 685...
669
            middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
685
            middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
670
            if( ! middle_header ) return ENOMEM;
686
            if( ! middle_header ) return ENOMEM;
671
            memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
687
            memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
672
            header->flags |= IPFLAG_MORE_FRAGMENTS;
688
            header->flags |= IPFLAG_MORE_FRAGMENTS;
673
            middle_header->total_length = htons( packet_get_data_length( next ));
689
            middle_header->total_length = htons( packet_get_data_length( next ));
674
            middle_header->fragment_offset = length / 8;
690
            middle_header->fragment_offset = IP_FRAGMENT_OFFSET( length );
675
            middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
691
            middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
676
            if( destination ){
692
            if( destination ){
677
                ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
693
                ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
678
            }
694
            }
679
            length += packet_get_data_length( next );
695
            length += packet_get_data_length( next );
Line 681... Line 697...
681
        }
697
        }
682
        middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
698
        middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
683
        if( ! middle_header ) return ENOMEM;
699
        if( ! middle_header ) return ENOMEM;
684
        memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
700
        memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
685
        middle_header->total_length = htons( packet_get_data_length( next ));
701
        middle_header->total_length = htons( packet_get_data_length( next ));
686
        middle_header->fragment_offset = length / 8;
702
        middle_header->fragment_offset = IP_FRAGMENT_OFFSET( length );
687
        middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
703
        middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
688
        if( destination ){
704
        if( destination ){
689
            ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
705
            ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
690
        }
706
        }
691
        length += packet_get_data_length( next );
707
        length += packet_get_data_length( next );
Line 699... Line 715...
699
}
715
}
700
 
716
 
701
int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
717
int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
702
    ERROR_DECLARE;
718
    ERROR_DECLARE;
703
 
719
 
704
    packet_t    packet;
720
    packet_t                packet;
-
 
721
    struct sockaddr *       addr;
-
 
722
    size_t                  addrlen;
-
 
723
    ip_pseudo_header_ref    header;
-
 
724
    size_t                  headerlen;
705
 
725
 
706
    * answer_count = 0;
726
    * answer_count = 0;
707
    switch( IPC_GET_METHOD( * call )){
727
    switch( IPC_GET_METHOD( * call )){
708
        case IPC_M_PHONE_HUNGUP:
728
        case IPC_M_PHONE_HUNGUP:
709
            return EOK;
729
            return EOK;
Line 724... Line 744...
724
            return ip_received_error_msg( 0, IPC_GET_DEVICE( call ), packet, IPC_GET_TARGET( call ), IPC_GET_ERROR( call ));
744
            return ip_received_error_msg( 0, IPC_GET_DEVICE( call ), packet, IPC_GET_TARGET( call ), IPC_GET_ERROR( call ));
725
        case NET_IP_ADD_ROUTE:
745
        case NET_IP_ADD_ROUTE:
726
            return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call ));
746
            return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call ));
727
        case NET_IP_SET_GATEWAY:
747
        case NET_IP_SET_GATEWAY:
728
            return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call ));
748
            return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call ));
-
 
749
        case NET_IP_GET_ROUTE:
-
 
750
            ERROR_PROPAGATE( data_receive(( void ** ) & addr, & addrlen ));
-
 
751
            ERROR_PROPAGATE( ip_get_route_req( 0, IP_GET_PROTOCOL( call ), addr, ( socklen_t ) addrlen, IPC_SET_DEVICE( answer ), & header, & headerlen ));
-
 
752
            * IP_SET_HEADERLEN( answer ) = headerlen;
-
 
753
            if( ! ERROR_OCCURRED( data_reply( & headerlen, sizeof( headerlen )))){
-
 
754
                ERROR_CODE = data_reply( header, headerlen );
-
 
755
            }
-
 
756
            free( header );
-
 
757
            return ERROR_CODE;
729
        case NET_IL_PACKET_SPACE:
758
        case NET_IL_PACKET_SPACE:
730
            ERROR_PROPAGATE( ip_packet_size_req( 0, IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer )));
759
            ERROR_PROPAGATE( ip_packet_size_req( 0, IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer )));
731
            * answer_count = 3;
760
            * answer_count = 3;
732
            return EOK;
761
            return EOK;
733
        case NET_IL_MTU_CHANGED:
762
        case NET_IL_MTU_CHANGED:
Line 1283... Line 1312...
1283
int ip_release_and_return( packet_t packet, int result ){
1312
int ip_release_and_return( packet_t packet, int result ){
1284
    pq_release( ip_globals.net_phone, packet_get_id( packet ));
1313
    pq_release( ip_globals.net_phone, packet_get_id( packet ));
1285
    return result;
1314
    return result;
1286
}
1315
}
1287
 
1316
 
-
 
1317
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 ){
-
 
1318
    struct sockaddr_in *    address_in;
-
 
1319
//  struct sockaddr_in6 *   address_in6;
-
 
1320
    in_addr_t *             dest;
-
 
1321
    in_addr_t *             src;
-
 
1322
    ip_route_ref            route;
-
 
1323
    ipv4_pseudo_header_ref  header_in;
-
 
1324
 
-
 
1325
    if( !( destination && ( addrlen > 0 ))) return EINVAL;
-
 
1326
    if( !( device_id && header && headerlen )) return EBADMEM;
-
 
1327
    if( addrlen < sizeof( struct sockaddr )){
-
 
1328
        return EINVAL;
-
 
1329
    }
-
 
1330
    switch( destination->sa_family ){
-
 
1331
        case AF_INET:
-
 
1332
            if( addrlen != sizeof( struct sockaddr_in )){
-
 
1333
                return EINVAL;
-
 
1334
            }
-
 
1335
            address_in = ( struct sockaddr_in * ) destination;
-
 
1336
            dest = & address_in->sin_addr;
-
 
1337
            break;
-
 
1338
        // TODO IPv6
-
 
1339
/*      case AF_INET6:
-
 
1340
            if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
-
 
1341
            address_in6 = ( struct sockaddr_in6 * ) dest;
-
 
1342
            address_in6.sin6_addr.s6_addr;
-
 
1343
*/      default:
-
 
1344
            return EAFNOSUPPORT;
-
 
1345
    }
-
 
1346
    fibril_rwlock_read_lock( & ip_globals.lock );
-
 
1347
    route = ip_find_route( * dest );
-
 
1348
    if( !( route && route->netif )){
-
 
1349
        fibril_rwlock_read_unlock( & ip_globals.lock );
-
 
1350
        return ENOENT;
-
 
1351
    }
-
 
1352
    * device_id = route->netif->device_id;
-
 
1353
    src = ip_netif_address( route->netif );
-
 
1354
    fibril_rwlock_read_unlock( & ip_globals.lock );
-
 
1355
    * headerlen = sizeof( * header_in );
-
 
1356
    header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen );
-
 
1357
    if( ! header_in ) return ENOMEM;
-
 
1358
    bzero( header_in, * headerlen );
-
 
1359
    header_in->destination_address = dest->s_addr;
-
 
1360
    header_in->source_address = src->s_addr;
-
 
1361
    header_in->protocol = protocol;
-
 
1362
    header_in->data_length = 0;
-
 
1363
    * header = ( ip_pseudo_header_ref ) header_in;
-
 
1364
    return EOK;
-
 
1365
}
-
 
1366
 
1288
/** @}
1367
/** @}
1289
 */
1368
 */