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 | */ |