Subversion Repositories HelenOS

Rev

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

Rev 4717 Rev 4720
Line 49... Line 49...
49
 
49
 
50
#include "../../err.h"
50
#include "../../err.h"
51
#include "../../messages.h"
51
#include "../../messages.h"
52
#include "../../modules.h"
52
#include "../../modules.h"
53
 
53
 
54
#include "../../include/net_interface.h"
54
#include "../../include/arp_interface.h"
55
#include "../../include/inet.h"
-
 
56
#include "../../include/socket_codes.h"
-
 
57
#include "../../include/byteorder.h"
55
#include "../../include/byteorder.h"
58
#include "../../include/crc.h"
56
#include "../../include/crc.h"
59
#include "../../include/device.h"
57
#include "../../include/device.h"
60
#include "../../include/arp_interface.h"
58
#include "../../include/icmp_client.h"
-
 
59
#include "../../include/icmp_codes.h"
61
#include "../../include/nil_interface.h"
60
#include "../../include/icmp_interface.h"
62
#include "../../include/il_interface.h"
61
#include "../../include/il_interface.h"
-
 
62
#include "../../include/in.h"
-
 
63
#include "../../include/in6.h"
-
 
64
#include "../../include/inet.h"
63
#include "../../include/ip_client.h"
65
#include "../../include/ip_client.h"
64
#include "../../include/ip_interface.h"
66
#include "../../include/ip_interface.h"
-
 
67
#include "../../include/net_interface.h"
-
 
68
#include "../../include/nil_interface.h"
65
#include "../../include/tl_interface.h"
69
#include "../../include/tl_interface.h"
66
#include "../../include/icmp_codes.h"
70
#include "../../include/socket_codes.h"
67
#include "../../include/icmp_interface.h"
-
 
68
#include "../../include/icmp_client.h"
71
#include "../../include/socket_errno.h"
69
#include "../../structures/measured_strings.h"
72
#include "../../structures/measured_strings.h"
70
#include "../../structures/module_map.h"
73
#include "../../structures/module_map.h"
71
#include "../../structures/packet/packet_client.h"
74
#include "../../structures/packet/packet_client.h"
72
 
75
 
73
#include "../../nil/nil_messages.h"
76
#include "../../nil/nil_messages.h"
Line 95... Line 98...
95
 */
98
 */
96
#define ARP_FILENAME            "/srv/arp"
99
#define ARP_FILENAME            "/srv/arp"
97
 
100
 
98
/** IP packet address length.
101
/** IP packet address length.
99
 */
102
 */
100
#define IP_ADDR                         sizeof( in_addr_t )
103
#define IP_ADDR                         sizeof( struct sockaddr_in6 )
101
 
104
 
102
/** IP packet prefix length.
105
/** IP packet prefix length.
103
 */
106
 */
104
#define IP_PREFIX                       sizeof( ip_header_t )
107
#define IP_PREFIX                       sizeof( ip_header_t )
105
 
108
 
Line 177... Line 180...
177
int ip_netif_initialize( ip_netif_ref ip_netif );
180
int ip_netif_initialize( ip_netif_ref ip_netif );
178
 
181
 
179
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 );
182
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 );
180
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination );
183
int ip_prepare_packet( in_addr_t * source, in_addr_t dest, packet_t packet, measured_string_ref destination );
181
 
184
 
182
packet_t    ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len, services_t error );
185
packet_t    ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error );
183
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, size_t addr_len );
186
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len );
184
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, void * src, void * dest, size_t address_length );
187
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 );
185
ip_header_ref   ip_create_middle_header( packet_t packet, ip_header_ref last );
188
ip_header_ref   ip_create_middle_header( packet_t packet, ip_header_ref last );
186
void ip_create_last_header( ip_header_ref last, ip_header_ref first );
189
void ip_create_last_header( ip_header_ref last, ip_header_ref first );
187
 
190
 
188
in_addr_t * ip_netif_address( ip_netif_ref netif );
191
in_addr_t * ip_netif_address( ip_netif_ref netif );
189
ip_route_ref    ip_find_route( in_addr_t destination );
192
ip_route_ref    ip_find_route( in_addr_t destination );
Line 505... Line 508...
505
}
508
}
506
 
509
 
507
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ){
510
int ip_send_msg( int il_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error ){
508
    ERROR_DECLARE;
511
    ERROR_DECLARE;
509
 
512
 
510
    int                 length;
513
    int                 addrlen;
511
    ip_netif_ref        netif;
514
    ip_netif_ref        netif;
512
    ip_route_ref        route;
515
    ip_route_ref        route;
-
 
516
    struct sockaddr *       addr;
-
 
517
    struct sockaddr_in *    address_in;
-
 
518
//  struct sockaddr_in6 *   address_in6;
513
    in_addr_t *         dest;
519
    in_addr_t *         dest;
514
    in_addr_t *         src;
520
    in_addr_t *         src;
515
    int                 phone;
521
    int                 phone;
516
 
522
 
517
    // addresses in the host byte order
523
    // addresses in the host byte order
518
    // should be the next hop address or the target destination address
524
    // should be the next hop address or the target destination address
519
    length = packet_get_addr( packet, NULL, ( uint8_t ** ) & dest );
525
    addrlen = packet_get_addr( packet, NULL, ( uint8_t ** ) & addr );
520
    if( length < 0 ){
526
    if( addrlen < 0 ){
521
        return ip_release_and_return( packet, length );
527
        return ip_release_and_return( packet, addrlen );
522
    }
528
    }
523
    // TODO IPv6
-
 
524
    if( length != IP_ADDR ){
529
    if( addrlen < sizeof( struct sockaddr )){
525
        return ip_release_and_return( packet, EINVAL );
530
        return ip_release_and_return( packet, EINVAL );
526
    }
531
    }
-
 
532
    switch( addr->sa_family ){
-
 
533
        case AF_INET:
-
 
534
            if( addrlen != sizeof( struct sockaddr_in )){
-
 
535
                return ip_release_and_return( packet, EINVAL );
-
 
536
            }
-
 
537
            address_in = ( struct sockaddr_in * ) addr;
-
 
538
            dest = & address_in->sin_addr;
-
 
539
            break;
-
 
540
        // TODO IPv6
-
 
541
/*      case AF_INET6:
-
 
542
            if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL;
-
 
543
            address_in6 = ( struct sockaddr_in6 * ) dest;
-
 
544
            address_in6.sin6_addr.s6_addr;
-
 
545
*/      default:
-
 
546
            return ip_release_and_return( packet, EAFNOSUPPORT );
-
 
547
    }
527
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
548
    fibril_rwlock_read_lock( & ip_globals.netifs_lock );
528
    // device specified?
549
    // device specified?
529
    if( device_id > 0 ){
550
    if( device_id > 0 ){
530
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
551
        netif = ip_netifs_find( & ip_globals.netifs, device_id );
531
        route = ip_netif_find_route( netif, * dest );
552
        route = ip_netif_find_route( netif, * dest );
532
    }else{
553
    }else{
533
        // TODO IPv6
-
 
534
        route = ip_find_route( * dest );
554
        route = ip_find_route( * dest );
535
        netif = route ? route->netif : NULL;
555
        netif = route ? route->netif : NULL;
536
    }
556
    }
537
    if( !( netif && route )){
557
    if( !( netif && route )){
538
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
558
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
Line 550... Line 570...
550
        || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr )))
570
        || ( !( ~(( dest->s_addr & ( ~ route->netmask.s_addr )) | route->netmask.s_addr )))
551
        || ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){
571
        || ( !( dest->s_addr & ( ~ route->netmask.s_addr )))){
552
            return ip_release_and_return( packet, EINVAL );
572
            return ip_release_and_return( packet, EINVAL );
553
        }
573
        }
554
    }
574
    }
555
    // to me?
-
 
556
    if( route->address.s_addr == dest->s_addr ){
-
 
557
        // TODO loopback deliver
-
 
558
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
-
 
559
        return ip_deliver_local( -1, packet, ( ip_header_ref ) packet_get_data( packet ), error );
-
 
560
    }
-
 
561
 
-
 
562
    src = ip_netif_address( netif );
575
    src = ip_netif_address( netif );
563
    if( ! src ){
576
    if( ! src ){
564
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
577
        fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
565
        return ip_release_and_return( packet, ENOENT );
578
        return ip_release_and_return( packet, ENOENT );
566
    }
579
    }
567
    if( ERROR_OCCURRED( ip_send_route( packet, netif, route, src, * dest, error ))){
580
    ERROR_CODE = ip_send_route( packet, netif, route, src, * dest, error );
568
        pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
569
    }
-
 
570
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
581
    fibril_rwlock_read_unlock( & ip_globals.netifs_lock );
571
    return ERROR_CODE;
582
    return ERROR_CODE;
572
}
583
}
573
 
584
 
574
in_addr_t * ip_netif_address( ip_netif_ref netif ){
585
in_addr_t * ip_netif_address( ip_netif_ref netif ){
Line 589... Line 600...
589
    // get destination hardware address
600
    // get destination hardware address
590
    if( netif->arp ){
601
    if( netif->arp ){
591
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
602
        destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr;
592
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
603
        destination.length = CONVERT_SIZE( dest.s_addr, char, 1 );
593
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
604
        if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){
594
            sleep( 1 );
605
//          sleep( 1 );
595
            ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
606
//          ERROR_PROPAGATE( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ));
-
 
607
            pq_release( ip_globals.net_phone, packet_get_id( packet ));
-
 
608
            return ERROR_CODE;
596
        }
609
        }
597
        if( !( translation && translation->value )){
610
        if( !( translation && translation->value )){
598
            if( translation ){
611
            if( translation ){
599
                free( translation );
612
                free( translation );
600
                free( data );
613
                free( data );
Line 833... Line 846...
833
    ip_globals.gateway.netif = netif;
846
    ip_globals.gateway.netif = netif;
834
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
847
    fibril_rwlock_write_unlock( & ip_globals.netifs_lock );
835
    return EOK;
848
    return EOK;
836
}
849
}
837
 
850
 
838
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, size_t addr_len, services_t error ){
851
packet_t ip_split_packet( packet_t packet, size_t prefix, size_t content, size_t suffix, socklen_t addr_len, services_t error ){
839
    size_t          length;
852
    size_t          length;
840
    packet_t        next;
853
    packet_t        next;
841
    packet_t        new_packet;
854
    packet_t        new_packet;
842
    int             result;
855
    int             result;
843
    int             phone;
856
    int             phone;
Line 872... Line 885...
872
        next = pq_next( next );
885
        next = pq_next( next );
873
    }
886
    }
874
    return packet;
887
    return packet;
875
}
888
}
876
 
889
 
877
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, size_t addr_len ){
890
int ip_fragment_packet( packet_t packet, size_t length, size_t prefix, size_t suffix, socklen_t addr_len ){
878
    ERROR_DECLARE;
891
    ERROR_DECLARE;
879
 
892
 
880
    packet_t        new_packet;
893
    packet_t        new_packet;
881
    ip_header_ref   header;
894
    ip_header_ref   header;
882
    ip_header_ref   middle_header;
895
    ip_header_ref   middle_header;
883
    ip_header_ref   last_header;
896
    ip_header_ref   last_header;
884
    uint8_t *       src;
897
    struct sockaddr *       src;
885
    uint8_t *       dest;
898
    struct sockaddr *       dest;
886
    size_t          address_length;
899
    socklen_t       addrlen;
887
    int             result;
900
    int             result;
888
 
901
 
889
    result = packet_get_addr( packet, & src, & dest );
902
    result = packet_get_addr( packet, ( uint8_t ** ) & src, ( uint8_t ** ) & dest );
890
    if( result <= 0 ) return EINVAL;
903
    if( result <= 0 ) return EINVAL;
891
    address_length = ( size_t ) result;
904
    addrlen = ( socklen_t ) result;
892
    if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
905
    if( packet_get_data_length( packet ) <= sizeof( ip_header_t )) return ENOMEM;
893
    // get header
906
    // get header
894
    header = ( ip_header_ref ) packet_get_data( packet );
907
    header = ( ip_header_ref ) packet_get_data( packet );
895
    if( ! header ) return EINVAL;
908
    if( ! header ) return EINVAL;
896
    // fragmentation forbidden?
909
    // fragmentation forbidden?
897
    if( header->flags & IPFLAG_DONT_FRAGMENT ){
910
    if( header->flags & IPFLAG_DONT_FRAGMENT ){
898
        return EPERM;
911
        return EPERM;
899
    }
912
    }
900
    // create the last fragment
913
    // create the last fragment
901
    new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, ((( size_t ) address_length > addr_len ) ? ( size_t ) address_length : addr_len ));
914
    new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen > addr_len ) ? addrlen : addr_len ));
902
    if( ! new_packet ) return ENOMEM;
915
    if( ! new_packet ) return ENOMEM;
903
    // allocate as much as originally
916
    // allocate as much as originally
904
    last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header ));
917
    last_header = ( ip_header_ref ) packet_suffix( new_packet, IP_HEADER_LENGTH( header ));
905
    if( ! last_header ){
918
    if( ! last_header ){
906
        return ip_release_and_return( packet, ENOMEM );
919
        return ip_release_and_return( packet, ENOMEM );
Line 911... Line 924...
911
        return ip_release_and_return( packet, ERROR_CODE );
924
        return ip_release_and_return( packet, ERROR_CODE );
912
    }
925
    }
913
    // biggest multiple of 8 lower than content
926
    // biggest multiple of 8 lower than content
914
    // TODO even fragmentation?
927
    // TODO even fragmentation?
915
    length = length & ( ~ 0x7 );// ( content / 8 ) * 8
928
    length = length & ( ~ 0x7 );// ( content / 8 ) * 8
916
    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, address_length ))){
929
    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 ))){
917
        return ip_release_and_return( packet, ERROR_CODE );
930
        return ip_release_and_return( packet, ERROR_CODE );
918
    }
931
    }
919
    // mark the first as fragmented
932
    // mark the first as fragmented
920
    header->flags |= IPFLAG_MORE_FRAGMENTS;
933
    header->flags |= IPFLAG_MORE_FRAGMENTS;
921
    // create middle framgents
934
    // create middle framgents
922
    while( IP_TOTAL_LENGTH( header ) > length ){
935
    while( IP_TOTAL_LENGTH( header ) > length ){
923
        new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( address_length >= addr_len ) ? address_length : addr_len ));
936
        new_packet = packet_get_4( ip_globals.net_phone, prefix, length, suffix, (( addrlen >= addr_len ) ? addrlen : addr_len ));
924
        if( ! new_packet ) return ENOMEM;
937
        if( ! new_packet ) return ENOMEM;
925
        middle_header = ip_create_middle_header( new_packet, last_header );
938
        middle_header = ip_create_middle_header( new_packet, last_header );
926
        if( ! middle_header ){
939
        if( ! middle_header ){
927
            return ip_release_and_return( packet, ENOMEM );
940
            return ip_release_and_return( packet, ENOMEM );
928
        }
941
        }
929
        if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, length - IP_HEADER_LENGTH( middle_header ), src, dest, address_length ))){
942
        if( ERROR_OCCURRED( ip_fragment_packet_data( packet, new_packet, header, middle_header, length - IP_HEADER_LENGTH( middle_header ), src, dest, addrlen ))){
930
            return ip_release_and_return( packet, ERROR_CODE );
943
            return ip_release_and_return( packet, ERROR_CODE );
931
        }
944
        }
932
    }
945
    }
933
    // finish the first fragment
946
    // finish the first fragment
934
    header->header_checksum = IP_HEADER_CHECKSUM( header );
947
    header->header_checksum = IP_HEADER_CHECKSUM( header );
935
    return EOK;
948
    return EOK;
936
}
949
}
937
 
950
 
938
int ip_fragment_packet_data( packet_t packet, packet_t new_packet, ip_header_ref header, ip_header_ref new_header, size_t length, void * src, void * dest, size_t address_length ){
951
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 ){
939
    ERROR_DECLARE;
952
    ERROR_DECLARE;
940
 
953
 
941
    void *          data;
954
    void *          data;
942
 
955
 
943
    data = packet_suffix( new_packet, length );
956
    data = packet_suffix( new_packet, length );
Line 946... Line 959...
946
    ERROR_PROPAGATE( packet_trim( packet, 0, length ));
959
    ERROR_PROPAGATE( packet_trim( packet, 0, length ));
947
    header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
960
    header->total_length = htons( IP_TOTAL_LENGTH( header ) - length );
948
    new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
961
    new_header->total_length = htons( IP_HEADER_LENGTH( new_header ) + length );
949
    new_header->fragment_offset = header->fragment_offset + IP_HEADER_DATA_LENGTH( header ) / 8;
962
    new_header->fragment_offset = header->fragment_offset + IP_HEADER_DATA_LENGTH( header ) / 8;
950
    new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
963
    new_header->header_checksum = IP_HEADER_CHECKSUM( new_header );
951
    ERROR_PROPAGATE( packet_set_addr( new_packet, src, dest, address_length ));
964
    ERROR_PROPAGATE( packet_set_addr( new_packet, ( const uint8_t * ) src, ( const uint8_t * ) dest, addrlen ));
952
    return pq_insert_after( packet, new_packet );
965
    return pq_insert_after( packet, new_packet );
953
}
966
}
954
 
967
 
955
ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){
968
ip_header_ref ip_create_middle_header( packet_t packet, ip_header_ref last ){
956
    ip_header_ref   middle;
969
    ip_header_ref   middle;
Line 1013... Line 1026...
1013
 
1026
 
1014
    ip_header_ref   header;
1027
    ip_header_ref   header;
1015
    in_addr_t       dest;
1028
    in_addr_t       dest;
1016
    ip_route_ref    route;
1029
    ip_route_ref    route;
1017
    int             phone;
1030
    int             phone;
-
 
1031
    struct sockaddr *   addr;
-
 
1032
    struct sockaddr_in  addr_in;
-
 
1033
//  struct sockaddr_in  addr_in6;
-
 
1034
    socklen_t       addrlen;
1018
 
1035
 
1019
    header = ( ip_header_ref ) packet_get_data( packet );
1036
    header = ( ip_header_ref ) packet_get_data( packet );
1020
    if( ! header ){
1037
    if( ! header ){
1021
        return ip_release_and_return( packet, ENOMEM );
1038
        return ip_release_and_return( packet, ENOMEM );
1022
    }
1039
    }
Line 1033... Line 1050...
1033
        }
1050
        }
1034
        return EINVAL;
1051
        return EINVAL;
1035
    }
1052
    }
1036
    // process ipopt and get destination
1053
    // process ipopt and get destination
1037
    dest = ip_get_destination( header );
1054
    dest = ip_get_destination( header );
-
 
1055
    // set the addrination address
-
 
1056
    switch( header->version ){
-
 
1057
        case IPVERSION:
-
 
1058
            addrlen = sizeof( addr_in );
-
 
1059
            bzero( & addr_in, addrlen );
-
 
1060
            addr_in.sin_family = AF_INET;
-
 
1061
            memcpy( & addr_in.sin_addr.s_addr, & dest, sizeof( dest ));
-
 
1062
            addr = ( struct sockaddr * ) & addr_in;
-
 
1063
            break;
-
 
1064
/*      case IPv6VERSION:
-
 
1065
            addrlen = sizeof( dest_in6 );
-
 
1066
            bzero( & dest_in6, addrlen );
-
 
1067
            dest_in6.sin6_family = AF_INET6;
-
 
1068
            memcpy( & dest_in6.sin6_addr.s6_addr, );
-
 
1069
            dest = ( struct sockaddr * ) & dest_in;
-
 
1070
            break;
-
 
1071
*/      default:
-
 
1072
            return EAFNOSUPPORT;
-
 
1073
    }
1038
    ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & dest.s_addr, IP_ADDR ));
1074
    ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) & addr, addrlen ));
1039
    route = ip_find_route( dest );
1075
    route = ip_find_route( dest );
1040
    if( ! route ){
1076
    if( ! route ){
1041
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1077
        phone = ip_prepare_icmp_and_get_phone( 0, packet, header );
1042
        if( phone >= 0 ){
1078
        if( phone >= 0 ){
1043
            // unreachable ICMP
1079
            // unreachable ICMP
Line 1079... Line 1115...
1079
            offset = icmp_client_process_packet( packet, & type, & code, NULL, NULL );
1115
            offset = icmp_client_process_packet( packet, & type, & code, NULL, NULL );
1080
            if( offset < 0 ){
1116
            if( offset < 0 ){
1081
                return ip_release_and_return( packet, ENOMEM );
1117
                return ip_release_and_return( packet, ENOMEM );
1082
            }
1118
            }
1083
            data = packet_get_data( packet );
1119
            data = packet_get_data( packet );
1084
            header = ( ip_header_ref ) data + offset;
1120
            header = ( ip_header_ref )( data + offset );
1085
            // destination host unreachable?
1121
            // destination host unreachable?
1086
            if(( type == ICMP_DEST_UNREACH ) && ( code == ICMP_HOST_UNREACH )){
1122
            if(( type == ICMP_DEST_UNREACH ) && ( code == ICMP_HOST_UNREACH )){
1087
                fibril_rwlock_read_lock( & ip_globals.netifs_lock );
1123
                fibril_rwlock_read_lock( & ip_globals.netifs_lock );
1088
                netif = ip_netifs_find( & ip_globals.netifs, device_id );
1124
                netif = ip_netifs_find( & ip_globals.netifs, device_id );
1089
                if( netif && netif->arp ){
1125
                if( netif && netif->arp ){
Line 1108... Line 1144...
1108
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ){
1144
int ip_deliver_local( device_id_t device_id, packet_t packet, ip_header_ref header, services_t error ){
1109
    ERROR_DECLARE;
1145
    ERROR_DECLARE;
1110
 
1146
 
1111
    ip_proto_ref    proto;
1147
    ip_proto_ref    proto;
1112
    int             phone;
1148
    int             phone;
-
 
1149
    services_t      service;
-
 
1150
    tl_received_msg_t   received_msg;
-
 
1151
    struct sockaddr *   src;
-
 
1152
    struct sockaddr *   dest;
-
 
1153
    struct sockaddr_in  src_in;
-
 
1154
    struct sockaddr_in  dest_in;
-
 
1155
//  struct sockaddr_in  src_in6;
-
 
1156
//  struct sockaddr_in  dest_in6;
-
 
1157
    socklen_t       addrlen;
1113
 
1158
 
1114
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
1159
    if(( header->flags & IPFLAG_MORE_FRAGMENTS ) || header->fragment_offset ){
1115
        // TODO fragmented
1160
        // TODO fragmented
1116
        return ENOTSUP;
1161
        return ENOTSUP;
1117
    }else{
1162
    }else{
-
 
1163
        switch( header->version ){
-
 
1164
            case IPVERSION:
-
 
1165
                addrlen = sizeof( src_in );
-
 
1166
                bzero( & src_in, addrlen );
-
 
1167
                src_in.sin_family = AF_INET;
-
 
1168
                memcpy( & dest_in, & src_in, addrlen );
-
 
1169
                memcpy( & src_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address ));
-
 
1170
                memcpy( & dest_in.sin_addr.s_addr, & header->destination_address, sizeof( header->destination_address ));
-
 
1171
                src = ( struct sockaddr * ) & src_in;
-
 
1172
                dest = ( struct sockaddr * ) & dest_in;
-
 
1173
                break;
-
 
1174
/*          case IPv6VERSION:
-
 
1175
                addrlen = sizeof( src_in6 );
-
 
1176
                bzero( & src_in6, addrlen );
-
 
1177
                src_in6.sin6_family = AF_INET6;
-
 
1178
                memcpy( & dest_in6, & src_in6, addrlen );
-
 
1179
                memcpy( & src_in6.sin6_addr.s6_addr, );
-
 
1180
                memcpy( & dest_in6.sin6_addr.s6_addr, );
-
 
1181
                src = ( struct sockaddr * ) & src_in;
-
 
1182
                dest = ( struct sockaddr * ) & dest_in;
-
 
1183
                break;
-
 
1184
*/          default:
-
 
1185
                return EAFNOSUPPORT;
-
 
1186
        }
1118
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) & header->source_address, ( uint8_t * ) & header->destination_address, IP_ADDR ));
1187
        ERROR_PROPAGATE( packet_set_addr( packet, ( uint8_t * ) src, ( uint8_t * ) dest, addrlen ));
1119
        fibril_rwlock_read_lock( & ip_globals.protos_lock );
1188
        fibril_rwlock_read_lock( & ip_globals.protos_lock );
1120
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
1189
        proto = ip_protos_find( & ip_globals.protos, header->protocol );
1121
        if( ! proto ){
1190
        if( ! proto ){
1122
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1191
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1123
            phone = ip_prepare_icmp_and_get_phone( error, packet, header );
1192
            phone = ip_prepare_icmp_and_get_phone( error, packet, header );
Line 1126... Line 1195...
1126
                icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet );
1195
                icmp_destination_unreachable_msg( phone, ICMP_PROT_UNREACH, 0, packet );
1127
            }
1196
            }
1128
            return ENOENT;
1197
            return ENOENT;
1129
        }
1198
        }
1130
        if( proto->received_msg ){
1199
        if( proto->received_msg ){
-
 
1200
            service = proto->service;
-
 
1201
            received_msg = proto->received_msg;
-
 
1202
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1131
            ERROR_CODE = proto->received_msg( device_id, packet, proto->service, error );
1203
            ERROR_CODE = received_msg( device_id, packet, service, error );
1132
        }else{
1204
        }else{
1133
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error );
1205
            ERROR_CODE = tl_received_msg( proto->phone, device_id, packet, proto->service, error );
-
 
1206
            fibril_rwlock_read_unlock( & ip_globals.protos_lock );
1134
        }
1207
        }
1135
        fibril_rwlock_read_unlock( & ip_globals.protos_lock );
-
 
1136
        return ERROR_CODE;
1208
        return ERROR_CODE;
1137
    }
1209
    }
1138
}
1210
}
1139
 
1211
 
1140
in_addr_t ip_get_destination( ip_header_ref header ){
1212
in_addr_t ip_get_destination( ip_header_ref header ){
Line 1145... Line 1217...
1145
    return destination;
1217
    return destination;
1146
}
1218
}
1147
 
1219
 
1148
int ip_prepare_icmp( packet_t packet, ip_header_ref header ){
1220
int ip_prepare_icmp( packet_t packet, ip_header_ref header ){
1149
    packet_t    next;
1221
    packet_t    next;
-
 
1222
    struct sockaddr *   dest;
-
 
1223
    struct sockaddr_in  dest_in;
-
 
1224
//  struct sockaddr_in  dest_in6;
-
 
1225
    socklen_t       addrlen;
1150
 
1226
 
1151
    // detach the first packet and release the others
1227
    // detach the first packet and release the others
1152
    next = pq_detach( packet );
1228
    next = pq_detach( packet );
1153
    if( next ){
1229
    if( next ){
1154
        pq_release( ip_globals.net_phone, packet_get_id( next ));
1230
        pq_release( ip_globals.net_phone, packet_get_id( next ));
Line 1160... Line 1236...
1160
        if( ! header ) return EINVAL;
1236
        if( ! header ) return EINVAL;
1161
    }
1237
    }
1162
    // only for the first fragment
1238
    // only for the first fragment
1163
    if( header->fragment_offset ) return EINVAL;
1239
    if( header->fragment_offset ) return EINVAL;
1164
    // set the destination address
1240
    // set the destination address
-
 
1241
    switch( header->version ){
-
 
1242
        case IPVERSION:
-
 
1243
            addrlen = sizeof( dest_in );
-
 
1244
            bzero( & dest_in, addrlen );
-
 
1245
            dest_in.sin_family = AF_INET;
1165
    return packet_set_addr( packet, NULL, ( uint8_t * ) & header->source_address, sizeof( header->source_address ));
1246
            memcpy( & dest_in.sin_addr.s_addr, & header->source_address, sizeof( header->source_address ));
-
 
1247
            dest = ( struct sockaddr * ) & dest_in;
-
 
1248
            break;
-
 
1249
/*      case IPv6VERSION:
-
 
1250
            addrlen = sizeof( dest_in6 );
-
 
1251
            bzero( & dest_in6, addrlen );
-
 
1252
            dest_in6.sin6_family = AF_INET6;
-
 
1253
            memcpy( & dest_in6.sin6_addr.s6_addr, );
-
 
1254
            dest = ( struct sockaddr * ) & dest_in;
-
 
1255
            break;
-
 
1256
*/      default:
-
 
1257
            return EAFNOSUPPORT;
-
 
1258
    }
-
 
1259
    return packet_set_addr( packet, NULL, ( uint8_t * ) dest, addrlen );
1166
}
1260
}
1167
 
1261
 
1168
int ip_get_icmp_phone( void ){
1262
int ip_get_icmp_phone( void ){
1169
    ip_proto_ref    proto;
1263
    ip_proto_ref    proto;
1170
    int             phone;
1264
    int             phone;