37,8 → 37,8 |
|
#include <async.h> |
#include <malloc.h> |
#include <mem.h> |
#include <stdio.h> |
#include <string.h> |
|
#include <ipc/ipc.h> |
#include <ipc/services.h> |
76,9 → 76,11 |
*/ |
#define IPC_GET_PACKET( call ) ( packet_id_t ) IPC_GET_ARG2( * call ) |
|
#define IPC_GET_STATE( call ) ( device_state_t ) IPC_GET_ARG2( * call ) |
|
/** Returns the protocol service message parameter. |
*/ |
#define IPC_GET_PROTO( call ) ( services_t ) IPC_GET_ARG1( * call ) |
#define IPC_GET_PROTO( call ) ( services_t ) IPC_GET_ARG2( * call ) |
|
/** Returns the device driver service message parameter. |
*/ |
123,7 → 125,7 |
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
int eth_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ); |
void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
eth_proto_ref eth_proccess_packet( int dummy, packet_t packet ); |
eth_proto_ref eth_process_packet( int dummy, packet_t packet ); |
int eth_prepare_packet( int dummy, packet_t packet, uint8_t * src_addr, int ethertype ); |
|
int eth_initialize( void ){ |
151,7 → 153,8 |
aid_t message; |
ipc_call_t answer; |
eth_device_ref device; |
int result; |
ipcarg_t result; |
int index; |
|
rwlock_write_lock( & eth_globals.devices_lock ); |
// an existing device? |
190,7 → 193,7 |
async_wait_for( message, NULL ); |
return ERROR_CODE; |
} |
async_wait_for( message, ( ipcarg_t * ) & result ); |
async_wait_for( message, & result ); |
if( ERROR_OCCURRED( result )){ |
rwlock_write_unlock( & eth_globals.devices_lock ); |
free( device->addr ); |
199,12 → 202,13 |
return ERROR_CODE; |
} |
// add to the cache |
if( ERROR_OCCURRED( eth_devices_add( & eth_globals.devices, device->device_id, device ))){ |
index = eth_devices_add( & eth_globals.devices, device->device_id, device ); |
if( index < 0 ){ |
rwlock_write_unlock( & eth_globals.devices_lock ); |
free( device->addr ); |
free( device->addr_data ); |
free( device ); |
return ERROR_CODE; |
return index; |
} |
printf( "\nNew device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n\taddress\t= %X:%X:%X:%X:%X:%X", device->device_id, device->service, device->mtu, device->addr_data[ 0 ], device->addr_data[ 1 ], device->addr_data[ 2 ], device->addr_data[ 3 ], device->addr_data[ 4 ], device->addr_data[ 5 ] ); |
} |
212,7 → 216,7 |
return EOK; |
} |
|
eth_proto_ref eth_proccess_packet( int dummy, packet_t packet ){ |
eth_proto_ref eth_process_packet( int dummy, packet_t packet ){ |
ERROR_DECLARE; |
|
eth_header_ex_ref header; |
286,12 → 290,12 |
rwlock_read_lock( & eth_globals.protos_lock ); |
do{ |
next = pq_detach( packet ); |
proto = eth_proccess_packet( dummy, packet ); |
proto = eth_process_packet( dummy, packet ); |
if( proto ){ |
async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet )); |
}else{ |
// drop invalid/unknown |
packet_release( eth_globals.networking_phone, packet_get_id( packet )); |
pq_release( eth_globals.networking_phone, packet_get_id( packet )); |
} |
packet = next; |
}while( packet ); |
303,14 → 307,14 |
eth_device_ref device; |
|
if( !( addr_len && prefix && content && suffix )) return EINVAL; |
rwlock_write_lock( & eth_globals.devices_lock ); |
rwlock_read_lock( & eth_globals.devices_lock ); |
device = eth_devices_find( & eth_globals.devices, device_id ); |
if( ! device ){ |
rwlock_write_unlock( & eth_globals.devices_lock ); |
rwlock_read_unlock( & eth_globals.devices_lock ); |
return ENOENT; |
} |
* content = ( ETH_MAX_CONTENT > device->mtu ) ? device->mtu : ETH_MAX_CONTENT; |
rwlock_write_unlock( & eth_globals.devices_lock ); |
rwlock_read_unlock( & eth_globals.devices_lock ); |
* addr_len = ETH_ADDR; |
* prefix = ETH_PREFIX; |
* suffix = ETH_MIN_CONTENT + ETH_SUFFIX; |
324,23 → 328,22 |
if( type == ETH_BROADCAST_ADDR ){ |
* address = eth_globals.broadcast_addr; |
}else{ |
rwlock_write_lock( & eth_globals.devices_lock ); |
rwlock_read_lock( & eth_globals.devices_lock ); |
device = eth_devices_find( & eth_globals.devices, device_id ); |
if( ! device ){ |
rwlock_write_unlock( & eth_globals.devices_lock ); |
rwlock_read_unlock( & eth_globals.devices_lock ); |
return ENOENT; |
} |
* address = device->addr; |
rwlock_write_unlock( & eth_globals.devices_lock ); |
rwlock_read_unlock( & eth_globals.devices_lock ); |
} |
return ( * address ) ? EOK : ENOENT; |
} |
|
int eth_register_message( services_t service, int phone ){ |
ERROR_DECLARE; |
|
eth_proto_ref proto; |
int protocol; |
int index; |
|
protocol = protocol_map( SERVICE_ETHERNET, service ); |
if( ! protocol ) return ENOENT; |
359,13 → 362,14 |
proto->service = service; |
proto->protocol = protocol; |
proto->phone = phone; |
if( ERROR_OCCURRED( eth_protos_add( & eth_globals.protos, protocol, proto ))){ |
index = eth_protos_add( & eth_globals.protos, protocol, proto ); |
if( index < 0 ){ |
rwlock_write_unlock( & eth_globals.protos_lock ); |
free( proto ); |
return ERROR_CODE; |
return index; |
} |
} |
printf( "\nNew protocol registered:\n\tprotocol\t= %d\n\tservice\t= %d\n\tphone\t= %d", proto->protocol, proto->service, proto->phone ); |
printf( "\nNew protocol registered:\n\tprotocol\t= 0x%x\n\tservice\t= %d\n\tphone\t= %d", proto->protocol, proto->service, proto->phone ); |
rwlock_write_unlock( & eth_globals.protos_lock ); |
return EOK; |
} |
398,7 → 402,7 |
if( length < ETH_MIN_CONTENT ){ |
padding = packet_suffix( packet, ETH_MIN_CONTENT - length ); |
if( ! padding ) return ENOMEM; |
memset( padding, 0, ETH_MIN_CONTENT - length ); |
bzero( padding, ETH_MIN_CONTENT - length ); |
} |
header->header.ethertype = htons( length ); |
header->lsap.dsap = 0xAA; |
424,7 → 428,7 |
|
ethertype = htons( protocol_map( SERVICE_ETHERNET, sender )); |
if( ! ethertype ){ |
packet_release( eth_globals.networking_phone, packet_get_id( packet )); |
pq_release( eth_globals.networking_phone, packet_get_id( packet )); |
return EINVAL; |
} |
rwlock_read_lock( & eth_globals.devices_lock ); |
433,13 → 437,13 |
rwlock_read_unlock( & eth_globals.devices_lock ); |
return ENOENT; |
} |
// proccess packet queue |
// process packet queue |
next = packet; |
do{ |
if( ERROR_OCCURRED( eth_prepare_packet( device->dummy, next, ( uint8_t * ) device->addr->value, ethertype ))){ |
// release invalid packet |
tmp = pq_detach( next ); |
packet_release( eth_globals.networking_phone, packet_get_id( next )); |
pq_release( eth_globals.networking_phone, packet_get_id( next )); |
next = tmp; |
}else{ |
next = pq_next( next ); |
471,18 → 475,11 |
* answer_count = 3; |
return EOK; |
case NET_NIL_ADDR: |
rwlock_read_lock( & eth_globals.devices_lock ); |
if( ! ERROR_OCCURRED( eth_addr_message( IPC_GET_DEVICE( call ), ETH_LOCAL_ADDR, & address ))){ |
ERROR_CODE = measured_strings_reply( address, 1 ); |
} |
rwlock_read_unlock( & eth_globals.devices_lock ); |
return ERROR_CODE; |
ERROR_PROPAGATE( eth_addr_message( IPC_GET_DEVICE( call ), ETH_LOCAL_ADDR, & address )); |
return measured_strings_reply( address, 1 ); |
case NET_NIL_BROADCAST_ADDR: |
rwlock_read_lock( & eth_globals.devices_lock ); |
if( ! ERROR_OCCURRED( eth_addr_message( IPC_GET_DEVICE( call ), ETH_BROADCAST_ADDR, & address ))){ |
ERROR_CODE = measured_strings_reply( address, 1 ); |
} |
rwlock_read_unlock( & eth_globals.devices_lock ); |
ERROR_PROPAGATE( eth_addr_message( IPC_GET_DEVICE( call ), ETH_BROADCAST_ADDR, & address )); |
return measured_strings_reply( address, 1 ); |
return ERROR_CODE; |
case IPC_M_CONNECT_TO_ME: |
return eth_register_message( IPC_GET_PROTO( call ), IPC_GET_PHONE( call )); |
494,11 → 491,20 |
ERROR_DECLARE; |
|
packet_t packet; |
int index; |
eth_proto_ref proto; |
|
while( true ){ |
switch( IPC_GET_METHOD( * icall )){ |
case NET_NIL_DEVICE_STATE: |
//TODO clear device if off? |
rwlock_read_lock( & eth_globals.protos_lock ); |
for( index = eth_protos_count( & eth_globals.protos ) - 1; index >= 0; -- index ){ |
proto = eth_protos_get_index( & eth_globals.protos, index ); |
if( proto && proto->phone ) async_msg_2( proto->phone, NET_IL_DEVICE_STATE, IPC_GET_DEVICE( icall ), IPC_GET_STATE( icall )); |
} |
rwlock_read_unlock( & eth_globals.protos_lock ); |
ipc_answer_0( iid, EOK ); |
break; |
case NET_NIL_RECEIVED: |
if( ! ERROR_OCCURRED( packet_translate( eth_globals.networking_phone, & packet, IPC_GET_PACKET( icall )))){ |