Subversion Repositories HelenOS

Rev

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

Rev 4728 Rev 4731
Line 402... Line 402...
402
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
402
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
403
    return EOK;
403
    return EOK;
404
}
404
}
405
 
405
 
406
int ip_device_state_message( device_id_t device_id, device_state_t state ){
406
int ip_device_state_message( device_id_t device_id, device_state_t state ){
407
//  ERROR_DECLARE;
-
 
408
 
-
 
409
/*  measured_string_t   address;
-
 
410
    measured_string_ref translation;
-
 
411
    char *              data;
-
 
412
*/
-
 
413
/*  packet_t        packet;
-
 
414
    in_addr_t       destination;
-
 
415
*/
-
 
416
    ip_netif_ref    netif;
407
    ip_netif_ref    netif;
417
 
408
 
418
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
409
    fibril_rwlock_write_lock( & ip_globals.netifs_lock );
-
 
410
    // find the device
419
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
411
    netif = ip_netifs_find( & ip_globals.netifs, device_id );
420
    if( ! netif ){
412
    if( ! netif ){
421
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
413
        fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
422
        return ENOENT;
414
        return ENOENT;
423
    }
415
    }
424
    netif->state = state;
416
    netif->state = state;
425
    // TODO state
-
 
426
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
417
    printf( "ip - device %d changed state to %d\n\n", device_id, state );
427
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
418
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
428
//  if( netif->arp ){
-
 
429
/*      address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
-
 
430
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
-
 
431
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
-
 
432
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
-
 
433
        }
-
 
434
        printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
-
 
435
        free( translation );
-
 
436
        free( data );
-
 
437
        address.value = ( char * ) & ip_globals.gateway.gateway.s_addr;
-
 
438
        address.length = CONVERT_SIZE( ip_globals.gateway.gateway.s_addr, char, 1 );
-
 
439
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ))){
-
 
440
            sleep( 2 );
-
 
441
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & address, & translation, & data ));
-
 
442
        }
-
 
443
        printf( "\tgateway translated to\t= %X:%X:%X:%X:%X:%X\n", data[ 0 ], data[ 1 ], data[ 2 ], data[ 3 ], data[ 4 ], data[ 5 ] );
-
 
444
        free( translation );
-
 
445
        free( data );
-
 
446
*//*        printf( "IP - testing to send packet:\n" );
-
 
447
        ERROR_PROPAGATE( inet_pton( AF_INET, "90.182.101.18", ( uint8_t * ) & destination.s_addr ));
-
 
448
        packet = packet_get_4( ip_globals.net_phone, 30, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
-
 
449
        if( ! packet ) return ENOMEM;
-
 
450
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
451
        packet = packet_get_4( ip_globals.net_phone, 30, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
-
 
452
        if( ! packet ) return ENOMEM;
-
 
453
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
454
        packet = packet_get_4( ip_globals.net_phone, 30, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
-
 
455
        if( ! packet ) return ENOMEM;
-
 
456
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
457
        packet = packet_get_4( ip_globals.net_phone, 1500, netif->addr_len, netif->prefix + sizeof( ip_header_t ), netif->suffix );
-
 
458
        if( ! packet ) return ENOMEM;
-
 
459
        // try this long version
-
 
460
//      if( ERROR_OCCURRED( packet_copy_data( packet, "Hi, this is IP, wery long version 1, wery long version 2, wery long version 3, wery long version 4, wery long version 5, wery long version 6, wery long version 7, wery long version 8, wery long version 9, wery long version 10, wery long version 11, wery long version 12, wery long version 13, wery long version 14, wery long version 15, wery long version 16, wery long version 17, wery long version 18, wery long version 19, wery long version 20, wery long version 21, wery long version 22, wery long version 23, wery long version 24, wery long version 25, wery long version 26, wery long version 27, wery long version 28, wery long version 29, wery long version 30Hi, this is IP, wery long version 1, wery long version 2, wery long version 3, wery long version 4, wery long version 5, wery long version 6, wery long version 7, wery long version 8, wery long version 9, wery long version 10, wery long version 11, wery long version 12, wery long version 13, wery long version 14, wery long version 15, wery long version 16, wery long version 17, wery long version 18, wery long version 19, wery long version 20, wery long version 21, wery long version 22, wery long version 23, wery long version 24, wery long version 25, wery long version 26, wery long version 27, wery long version 28, wery long version 29, wery long version 30", 1330 ))
-
 
461
        if( ERROR_OCCURRED( packet_copy_data( packet, "Hi, this is IP", 14 ))
-
 
462
        || ERROR_OCCURRED( packet_set_addr( packet, NULL, ( uint8_t * ) & destination.s_addr, 4 ))
-
 
463
        || ERROR_OCCURRED( ip_client_prepare_packet( packet, 0, 0, 0, 0, 0 ))){
-
 
464
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
465
        }
-
 
466
        ERROR_CODE = ip_send_msg( 0, 0, packet, SERVICE_IP );
-
 
467
        printf( "send returned %d\n", ERROR_CODE );
-
 
468
    }
-
 
469
*/  return EOK;
419
    return EOK;
470
}
420
}
471
 
421
 
472
int ip_connect_module( services_t service ){
422
int ip_connect_module( services_t service ){
473
    return EOK;
423
    return EOK;
474
}
424
}
Line 659... Line 609...
659
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
609
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
660
    }else{
610
    }else{
661
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0 ));
611
        ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0 ));
662
    }
612
    }
663
    header->version = IPV4;
613
    header->version = IPV4;
-
 
614
    header->fragment_offset_high = 0;
664
    header->fragment_offset = 0;
615
    header->fragment_offset_low = 0;
665
    header->header_checksum = 0;
616
    header->header_checksum = 0;
666
    if( source ) header->source_address = source->s_addr;
617
    if( source ) header->source_address = source->s_addr;
667
    header->destination_address = dest.s_addr;
618
    header->destination_address = dest.s_addr;
668
    fibril_rwlock_write_lock( & ip_globals.lock );
619
    fibril_rwlock_write_lock( & ip_globals.lock );
669
    ++ ip_globals.packet_counter;
620
    ++ ip_globals.packet_counter;
670
    header->identification = htons( ip_globals.packet_counter );
621
    header->identification = htons( ip_globals.packet_counter );
671
    fibril_rwlock_write_unlock( & ip_globals.lock );
622
    fibril_rwlock_write_unlock( & ip_globals.lock );
672
    length = packet_get_data_length( packet );
623
//  length = packet_get_data_length( packet );
673
    if( pq_next( packet )){
624
    if( pq_next( packet )){
674
        last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header ));
625
        last_header = ( ip_header_ref ) malloc( IP_HEADER_LENGTH( header ));
675
        if( ! last_header ) return ENOMEM;
626
        if( ! last_header ) return ENOMEM;
676
        ip_create_last_header( last_header, header );
627
        ip_create_last_header( last_header, header );
677
        next = pq_next( packet );
628
        next = pq_next( packet );
Line 679... Line 630...
679
            middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
630
            middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
680
            if( ! middle_header ) return ENOMEM;
631
            if( ! middle_header ) return ENOMEM;
681
            memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
632
            memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
682
            header->flags |= IPFLAG_MORE_FRAGMENTS;
633
            header->flags |= IPFLAG_MORE_FRAGMENTS;
683
            middle_header->total_length = htons( packet_get_data_length( next ));
634
            middle_header->total_length = htons( packet_get_data_length( next ));
-
 
635
            middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length );
684
            middle_header->fragment_offset = IP_COMPUTE_FRAGMENT_OFFSET( length );
636
            middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length );
685
            middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
637
            middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
686
            if( destination ){
638
            if( destination ){
687
                ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
639
                ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
688
            }
640
            }
689
            length += packet_get_data_length( next );
641
            length += packet_get_data_length( next );
Line 691... Line 643...
691
        }
643
        }
692
        middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
644
        middle_header = ( ip_header_ref ) packet_prefix( next, IP_HEADER_LENGTH( last_header ));
693
        if( ! middle_header ) return ENOMEM;
645
        if( ! middle_header ) return ENOMEM;
694
        memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
646
        memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header ));
695
        middle_header->total_length = htons( packet_get_data_length( next ));
647
        middle_header->total_length = htons( packet_get_data_length( next ));
-
 
648
        middle_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( length );
696
        middle_header->fragment_offset = IP_COMPUTE_FRAGMENT_OFFSET( length );
649
        middle_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( length );
697
        middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
650
        middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header );
698
        if( destination ){
651
        if( destination ){
699
            ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
652
            ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length )));
700
        }
653
        }
701
        length += packet_get_data_length( next );
654
        length += packet_get_data_length( next );
Line 947... Line 900...
947
        return ip_release_and_return( packet, ERROR_CODE );
900
        return ip_release_and_return( packet, ERROR_CODE );
948
    }
901
    }
949
    // biggest multiple of 8 lower than content
902
    // biggest multiple of 8 lower than content
950
    // TODO even fragmentation?
903
    // TODO even fragmentation?
951
    length = length & ( ~ 0x7 );// ( content / 8 ) * 8
904
    length = length & ( ~ 0x7 );// ( content / 8 ) * 8
952
    if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, last_header, (( IP_TOTAL_LENGTH( header ) - length ) % ( length - IP_HEADER_LENGTH( last_header ))), src, dest, addrlen ))){
905
    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 ))){
953
        return ip_release_and_return( packet, ERROR_CODE );
906
        return ip_release_and_return( packet, ERROR_CODE );
954
    }
907
    }
955
    // mark the first as fragmented
908
    // mark the first as fragmented
956
    header->flags |= IPFLAG_MORE_FRAGMENTS;
909
    header->flags |= IPFLAG_MORE_FRAGMENTS;
957
    // create middle framgents
910
    // create middle framgents
Line 960... Line 913...
960
        if( ! new_packet ) return ENOMEM;
913
        if( ! new_packet ) return ENOMEM;
961
        middle_header = ip_create_middle_header( new_packet, last_header );
914
        middle_header = ip_create_middle_header( new_packet, last_header );
962
        if( ! middle_header ){
915
        if( ! middle_header ){
963
            return ip_release_and_return( packet, ENOMEM );
916
            return ip_release_and_return( packet, ENOMEM );
964
        }
917
        }
965
        if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, length - IP_HEADER_LENGTH( middle_header ), src, dest, addrlen ))){
918
        if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, ( length - IP_HEADER_LENGTH( middle_header )) & ( ~ 0x7 ), src, dest, addrlen ))){
966
            return ip_release_and_return( packet, ERROR_CODE );
919
            return ip_release_and_return( packet, ERROR_CODE );
967
        }
920
        }
968
    }
921
    }
969
    // finish the first fragment
922
    // finish the first fragment
970
    header->header_checksum = IP_HEADER_CHECKSUM( header );
923
    header->header_checksum = IP_HEADER_CHECKSUM( header );
Line 973... Line 926...
973
 
926
 
974
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 ){
927
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 ){
975
    ERROR_DECLARE;
928
    ERROR_DECLARE;
976
 
929
 
977
    void *          data;
930
    void *          data;
-
 
931
    size_t          offset;
978
 
932
 
979
    data = packet_suffix( new_packet, length );
933
    data = packet_suffix( new_packet, length );
980
    if( ! data ) return ENOMEM;
934
    if( ! data ) return ENOMEM;
981
    memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length );
935
    memcpy( data, (( void * ) header ) + IP_TOTAL_LENGTH( header ) - length, length );
982
    ERROR_PROPAGATE( packet_trim( packet, 0, length ));
936
    ERROR_PROPAGATE( packet_trim( packet, 0, length ));
983
    header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
937
    header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
984
    new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
938
    new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
985
    new_header->fragment_offset = header->fragment_offset + IP_HEADER_DATA_LENGTH( header ) / 8;
939
    offset = IP_FRAGMENT_OFFSET( header ) + IP_HEADER_DATA_LENGTH( header );
-
 
940
    printf( "offset %d = %d + %d\n", offset, IP_FRAGMENT_OFFSET( header ), IP_HEADER_DATA_LENGTH( header ));
-
 
941
    new_header->fragment_offset_high = IP_COMPUTE_FRAGMENT_OFFSET_HIGH( offset );
-
 
942
    new_header->fragment_offset_low = IP_COMPUTE_FRAGMENT_OFFSET_LOW( offset );
986
    new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
943
    new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
987
    ERROR_PROPAGATE( packet_set_addr( new_packet, ( const uint8_t * ) src, ( const uint8_t * ) dest, addrlen ));
944
    ERROR_PROPAGATE( packet_set_addr( new_packet, ( const uint8_t * ) src, ( const uint8_t * ) dest, addrlen ));
988
    return pq_insert_after( packet, new_packet );
945
    return pq_insert_after( packet, new_packet );
989
}
946
}
990
 
947
 
Line 1060... Line 1017...
1060
    if( ! header ){
1017
    if( ! header ){
1061
        return ip_release_and_return( packet, ENOMEM );
1018
        return ip_release_and_return( packet, ENOMEM );
1062
    }
1019
    }
1063
    // checksum
1020
    // checksum
1064
    if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ))){
1021
    if(( header->header_checksum ) && ( IP_HEADER_CHECKSUM( header ))){
-
 
1022
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
-
 
1023
        if( phone >= 0 ){
1065
        // TODO checksum error ICMP?
1024
            // checksum error ICMP
-
 
1025
            icmp_parameter_problem_msg( phone, ICMP_PARAM_POINTER, (( size_t ) (( void * ) & header->header_checksum )) - (( size_t ) (( void * ) header )), packet );
-
 
1026
        }
1066
        return ip_release_and_return( packet, EINVAL );
1027
        return EINVAL;
1067
    }
1028
    }
1068
    if( header->ttl <= 1 ){
1029
    if( header->ttl <= 1 ){
1069
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1030
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1070
        if( phone >= 0 ){
1031
        if( phone >= 0 ){
1071
            // ttl oxceeded ICMP
1032
            // ttl oxceeded ICMP
Line 1177... Line 1138...
1177
    struct sockaddr_in  dest_in;
1138
    struct sockaddr_in  dest_in;
1178
//  struct sockaddr_in  src_in6;
1139
//  struct sockaddr_in  src_in6;
1179
//  struct sockaddr_in  dest_in6;
1140
//  struct sockaddr_in  dest_in6;
1180
    socklen_t       addrlen;
1141
    socklen_t       addrlen;
1181
 
1142
 
1182
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
1143
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || IP_FRAGMENT_OFFSET( header )){
1183
        // TODO fragmented
1144
        // TODO fragmented
1184
        return ENOTSUP;
1145
        return ENOTSUP;
1185
    }else{
1146
    }else{
1186
        switch( header->version ){
1147
        switch( header->version ){
1187
            case IPVERSION:
1148
            case IPVERSION:
Line 1257... Line 1218...
1257
        // get header
1218
        // get header
1258
        header = ( ip_header_ref ) packet_get_data( packet );
1219
        header = ( ip_header_ref ) packet_get_data( packet );
1259
        if( ! header ) return EINVAL;
1220
        if( ! header ) return EINVAL;
1260
    }
1221
    }
1261
    // only for the first fragment
1222
    // only for the first fragment
1262
    if( header->fragment_offset ) return EINVAL;
1223
    if( IP_FRAGMENT_OFFSET( header )) return EINVAL;
1263
    // set the destination address
1224
    // set the destination address
1264
    switch( header->version ){
1225
    switch( header->version ){
1265
        case IPVERSION:
1226
        case IPVERSION:
1266
            addrlen = sizeof( dest_in );
1227
            addrlen = sizeof( dest_in );
1267
            bzero( & dest_in, addrlen );
1228
            bzero( & dest_in, addrlen );