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; |