Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4242 → Rev 4243

/branches/network/uspace/srv/net/il/arp/arp.c
48,8 → 48,9
#include "../../messages.h"
#include "../../modules.h"
 
#include "../../include/byteorder.h"
#include "../../include/device.h"
#include "../../include/protocol_map.h"
#include "../../netif/device.h"
 
#include "../../structures/measured_strings.h"
#include "../../structures/packet/packet.h"
223,7 → 224,7
}
printf( "\nCache of the existing device %d cleaned", device->device_id );
}else{
index = protocol_map( service, protocol );
index = hardware_map( service );
if( ! index ) return ENOENT;
// create a new device
device = ( arp_device_ref ) malloc( sizeof( arp_device_t ));
319,39 → 320,23
arp_header_ref header;
 
if( ! target ) return NULL;
rwlock_read_lock( & arp_globals.lock );
device = arp_cache_find( & arp_globals.cache, device_id );
if( ! device ){
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
if( ! device ) return NULL;
proto = arp_protos_find( & device->protos, protocol );
if(( ! proto ) || ( proto->addr->length != target->length )){
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
if(( ! proto ) || ( proto->addr->length != target->length )) return NULL;
addr = arp_addr_find( & proto->addresses, target->value, target->length );
if( addr ){
rwlock_read_unlock( & arp_globals.lock );
return addr;
}
if( addr ) return addr;
// ARP packet content size = header + ( address + translation ) * 2
length = 8 + ( CONVERT_SIZE( char, uint8_t, proto->addr->length ) + CONVERT_SIZE( char, uint8_t, device->addr->length )) * 2;
if( length > device->content ){
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
if( length > device->content ) return NULL;
packet = packet_get_4( arp_globals.networking_phone, device->addr_len, device->prefix, length, device->suffix );
if( ! packet ){
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
if( ! packet ) return NULL;
header = ( arp_header_ref ) packet_suffix( packet, length );
header->hardware = device->hardware;
header->hardware = htons( device->hardware );
header->hardware_length = device->addr->length;
header->protocol = protocol_map( device->service, protocol );
header->protocol = htons( protocol_map( device->service, protocol ));
header->protocol_length = proto->addr->length;
header->operation = ARPOP_REQUEST;
header->operation = htons( ARPOP_REQUEST );
length = sizeof( arp_header_t );
memcpy((( uint8_t * ) header ) + length, device->addr->value, device->addr->length );
length += device->addr->length;
361,8 → 346,7
length += device->addr->length;
memcpy((( uint8_t * ) header ) + length, target->value, target->length );
packet_set_addr( packet, ( uint8_t * ) device->addr->value, ( uint8_t * ) device->broadcast_addr->value, CONVERT_SIZE( char, uint8_t, device->addr->length ));
async_msg_3( device->phone, NET_NETIF_SEND, device_id, SERVICE_ARP, packet_get_id( packet ));
rwlock_read_unlock( & arp_globals.lock );
async_msg_3( device->phone, NET_NIL_SEND, device_id, packet_get_id( packet ), SERVICE_ARP );
return NULL;
}
 
381,23 → 365,15
 
length = packet_get_data_length( packet );
if( length <= sizeof( arp_header_t )) return EINVAL;
rwlock_read_lock( & arp_globals.lock );
device = arp_cache_find( & arp_globals.cache, device_id );
if( ! device ){
rwlock_read_unlock( & arp_globals.lock );
return ENOENT;
}
if( ! device ) return ENOENT;
header = ( arp_header_ref ) packet_get_data( packet );
if(( header->hardware != device->hardware )
if(( ntohs( header->hardware ) != device->hardware )
|| ( length < sizeof( arp_header_t ) + ( header->hardware_length + header->protocol_length ) * 2 )){
rwlock_read_unlock( & arp_globals.lock );
return EINVAL;
}
proto = arp_protos_find( & device->protos, protocol_unmap( device->service, header->protocol ));
if( ! proto ){
rwlock_read_unlock( & arp_globals.lock );
return ENOENT;
}
proto = arp_protos_find( & device->protos, protocol_unmap( device->service, ntohs( header->protocol )));
if( ! proto ) return ENOENT;
src_hw = (( uint8_t * ) header ) + sizeof( arp_header_t );
src_proto = src_hw + header->hardware_length;
des_hw = src_proto + header->protocol_length;
406,7 → 382,6
// exists?
if( hw_source ){
if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){
rwlock_read_unlock( & arp_globals.lock );
return EINVAL;
}
memcpy( hw_source->value, src_hw, hw_source->length );
413,7 → 388,6
}
// is my protocol address?
if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){
rwlock_read_unlock( & arp_globals.lock );
return EINVAL;
}
if( ! strncmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){
420,26 → 394,18
// not already upadted?
if( ! hw_source ){
hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length ));
if( ! hw_source ){
rwlock_read_unlock( & arp_globals.lock );
return ENOMEM;
}
if( ERROR_OCCURRED( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source ))){
rwlock_read_unlock( & arp_globals.lock );
return ERROR_CODE;
}
if( ! hw_source ) return ENOMEM;
ERROR_PROPAGATE( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source ));
}
if( header->operation == ARPOP_REQUEST ){
header->operation = ARPOP_REPLY;
if( ntohs( header->operation ) == ARPOP_REQUEST ){
header->operation = htons( ARPOP_REPLY );
memcpy( des_proto, src_proto, header->protocol_length );
memcpy( src_proto, proto->addr->value, header->protocol_length );
memcpy( src_hw, des_hw, header->hardware_length );
memcpy( des_hw, hw_source->value, header->hardware_length );
packet_set_addr( packet, src_hw, des_hw, header->hardware_length );
async_msg_3( device->phone, NET_NETIF_SEND, device_id, SERVICE_ARP, packet_get_id( packet ));
rwlock_read_unlock( & arp_globals.lock );
async_msg_3( device->phone, NET_NIL_SEND, device_id, packet_get_id( packet ), SERVICE_ARP );
}else{
rwlock_read_unlock( & arp_globals.lock );
pq_release( arp_globals.networking_phone, packet_get_id( packet ));
}
}
502,6 → 468,7
measured_string_ref translation;
char * data;
 
// printf( "\nmessage %d - %d", IPC_GET_METHOD( * call ), NET_ARP_FIRST );
* answer_count = 0;
switch( IPC_GET_METHOD( * call )){
case IPC_M_PHONE_HUNGUP:
515,11 → 482,17
return ERROR_CODE;
case NET_ARP_TRANSLATE:
ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1 ));
rwlock_read_lock( & arp_globals.lock );
translation = arp_translate_message( IPC_GET_DEVICE( call ), IPC_GET_PROTO( call ), address );
free( address );
free( data );
if( ! translation ) return ENOENT;
return measured_strings_reply( translation, 1 );
if( ! translation ){
rwlock_read_unlock( & arp_globals.lock );
return ENOENT;
}
ERROR_CODE = measured_strings_reply( translation, 1 );
rwlock_read_unlock( & arp_globals.lock );
return ERROR_CODE;
case NET_ARP_CLEAR_DEVICE:
return arp_clear_device_message( IPC_GET_DEVICE( call ));
case NET_ARP_CLEAN_CACHE:
541,7 → 514,9
break;
case NET_IL_RECEIVED:
if( ! ERROR_OCCURRED( packet_translate( arp_globals.networking_phone, & packet, IPC_GET_PACKET( icall )))){
rwlock_read_lock( & arp_globals.lock );
ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( icall ), packet );
rwlock_read_unlock( & arp_globals.lock );
}
ipc_answer_0( iid, ERROR_CODE );
break;