82,18 → 82,10 |
#include "ip_messages.h" |
#include "ip_module.h" |
|
/** IP version 4. |
/** Default IP version. |
*/ |
#define IPV4 4 |
#define DEFAULT_IPV 4 |
|
/** Default network interface IP version. |
*/ |
#define NET_DEFAULT_IPV IPV4 |
|
/** Default network interface IP routing. |
*/ |
#define NET_DEFAULT_IP_ROUTING false |
|
/** Minimum IP packet content. |
*/ |
#define IP_MIN_CONTENT 576 |
142,11 → 134,6 |
*/ |
#define IP_HEADER_CHECKSUM( header ) ( htons( ip_checksum(( uint8_t * )( header ), IP_HEADER_LENGTH( header )))) |
|
/** Returns the fragment offest. |
* @param length The prefixed data total length. Input parameter. |
*/ |
#define IP_FRAGMENT_OFFSET( length ) (( length ) / 8 ) |
|
/** IP global data. |
*/ |
ip_globals_t ip_globals; |
317,9 → 304,6 |
|
ip_netif->arp = NULL; |
route = NULL; |
ip_netif->ipv = NET_DEFAULT_IPV; |
ip_netif->dhcp = false; |
ip_netif->routing = NET_DEFAULT_IP_ROUTING; |
configuration = & names[ 0 ]; |
// get configuration |
ERROR_PROPAGATE( net_get_device_conf_req( ip_globals.net_phone, ip_netif->device_id, & configuration, count, & data )); |
326,6 → 310,8 |
if( configuration ){ |
if( configuration[ 0 ].value ){ |
ip_netif->ipv = strtol( configuration[ 0 ].value, NULL, 0 ); |
}else{ |
ip_netif->ipv = DEFAULT_IPV; |
} |
ip_netif->dhcp = ! str_lcmp( configuration[ 1 ].value, "dhcp", configuration[ 1 ].length ); |
if( ip_netif->dhcp ){ |
332,7 → 318,7 |
// TODO dhcp |
net_free_settings( configuration, data ); |
return ENOTSUP; |
}else if( ip_netif->ipv == IPV4 ){ |
}else if( ip_netif->ipv == 4 ){ |
route = ( ip_route_ref ) malloc( sizeof( ip_route_t )); |
if( ! route ){ |
net_free_settings( configuration, data ); |
369,10 → 355,10 |
net_free_settings( configuration, data ); |
return EINVAL; |
} |
}else{ |
ip_netif->arp = NULL; |
} |
if( configuration[ 9 ].value ){ |
ip_netif->routing = ( configuration[ 9 ].value[ 0 ] == 'y' ); |
} |
ip_netif->routing = configuration[ 9 ].value && ( configuration[ 9 ].value[ 0 ] == 'y' ); |
net_free_settings( configuration, data ); |
} |
// binds the netif service which also initializes the device |
612,7 → 598,7 |
int phone; |
|
// get destination hardware address |
if( netif->arp && ( route->address.s_addr != dest.s_addr )){ |
if( netif->arp ){ |
destination.value = route->gateway.s_addr ? ( char * ) & route->gateway.s_addr : ( char * ) & dest.s_addr; |
destination.length = CONVERT_SIZE( dest.s_addr, char, 1 ); |
if( ERROR_OCCURRED( arp_translate_req( netif->arp->phone, netif->device_id, SERVICE_IP, & destination, & translation, & data ))){ |
663,10 → 649,8 |
header = ( ip_header_ref ) packet_get_data( packet ); |
if( destination ){ |
ERROR_PROPAGATE( packet_set_addr( packet, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); |
}else{ |
ERROR_PROPAGATE( packet_set_addr( packet, NULL, NULL, 0 )); |
} |
header->version = IPV4; |
header->version = 4; |
header->fragment_offset = 0; |
header->header_checksum = 0; |
if( source ) header->source_address = source->s_addr; |
687,7 → 671,7 |
memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header )); |
header->flags |= IPFLAG_MORE_FRAGMENTS; |
middle_header->total_length = htons( packet_get_data_length( next )); |
middle_header->fragment_offset = IP_FRAGMENT_OFFSET( length ); |
middle_header->fragment_offset = length / 8; |
middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header ); |
if( destination ){ |
ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); |
699,7 → 683,7 |
if( ! middle_header ) return ENOMEM; |
memcpy( middle_header, last_header, IP_HEADER_LENGTH( last_header )); |
middle_header->total_length = htons( packet_get_data_length( next )); |
middle_header->fragment_offset = IP_FRAGMENT_OFFSET( length ); |
middle_header->fragment_offset = length / 8; |
middle_header->header_checksum = IP_HEADER_CHECKSUM( middle_header ); |
if( destination ){ |
ERROR_PROPAGATE( packet_set_addr( next, NULL, ( uint8_t * ) destination->value, CONVERT_SIZE( char, uint8_t, destination->length ))); |
717,11 → 701,7 |
int ip_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ |
ERROR_DECLARE; |
|
packet_t packet; |
struct sockaddr * addr; |
size_t addrlen; |
ip_pseudo_header_ref header; |
size_t headerlen; |
packet_t packet; |
|
* answer_count = 0; |
switch( IPC_GET_METHOD( * call )){ |
746,15 → 726,6 |
return ip_add_route_req( 0, IPC_GET_DEVICE( call ), IP_GET_ADDRESS( call ), IP_GET_NETMASK( call ), IP_GET_GATEWAY( call )); |
case NET_IP_SET_GATEWAY: |
return ip_set_gateway_req( 0, IPC_GET_DEVICE( call ), IP_GET_GATEWAY( call )); |
case NET_IP_GET_ROUTE: |
ERROR_PROPAGATE( data_receive(( void ** ) & addr, & addrlen )); |
ERROR_PROPAGATE( ip_get_route_req( 0, IP_GET_PROTOCOL( call ), addr, ( socklen_t ) addrlen, IPC_SET_DEVICE( answer ), & header, & headerlen )); |
* IP_SET_HEADERLEN( answer ) = headerlen; |
if( ! ERROR_OCCURRED( data_reply( & headerlen, sizeof( headerlen )))){ |
ERROR_CODE = data_reply( header, headerlen ); |
} |
free( header ); |
return ERROR_CODE; |
case NET_IL_PACKET_SPACE: |
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 ))); |
* answer_count = 3; |
1314,55 → 1285,5 |
return result; |
} |
|
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 ){ |
struct sockaddr_in * address_in; |
// struct sockaddr_in6 * address_in6; |
in_addr_t * dest; |
in_addr_t * src; |
ip_route_ref route; |
ipv4_pseudo_header_ref header_in; |
|
if( !( destination && ( addrlen > 0 ))) return EINVAL; |
if( !( device_id && header && headerlen )) return EBADMEM; |
if( addrlen < sizeof( struct sockaddr )){ |
return EINVAL; |
} |
switch( destination->sa_family ){ |
case AF_INET: |
if( addrlen != sizeof( struct sockaddr_in )){ |
return EINVAL; |
} |
address_in = ( struct sockaddr_in * ) destination; |
dest = & address_in->sin_addr; |
break; |
// TODO IPv6 |
/* case AF_INET6: |
if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; |
address_in6 = ( struct sockaddr_in6 * ) dest; |
address_in6.sin6_addr.s6_addr; |
*/ default: |
return EAFNOSUPPORT; |
} |
fibril_rwlock_read_lock( & ip_globals.lock ); |
route = ip_find_route( * dest ); |
if( !( route && route->netif )){ |
fibril_rwlock_read_unlock( & ip_globals.lock ); |
return ENOENT; |
} |
* device_id = route->netif->device_id; |
src = ip_netif_address( route->netif ); |
fibril_rwlock_read_unlock( & ip_globals.lock ); |
* headerlen = sizeof( * header_in ); |
header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen ); |
if( ! header_in ) return ENOMEM; |
bzero( header_in, * headerlen ); |
header_in->destination_address = dest->s_addr; |
header_in->source_address = src->s_addr; |
header_in->protocol = protocol; |
header_in->data_length = 0; |
* header = ( ip_pseudo_header_ref ) header_in; |
return EOK; |
} |
|
/** @} |
*/ |