Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4152 → Rev 4153

/branches/network/uspace/srv/net/nil/eth/eth.c
123,8 → 123,8
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( packet_t packet );
int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype );
eth_proto_ref eth_proccess_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 ){
ERROR_DECLARE;
173,6 → 173,8
device->device_id = device_id;
device->service = service;
device->mtu = mtu;
// TODO get dummy setting
device->dummy = 0;
// bind the device driver
device->phone = bind_service( device->service, device->device_id, SERVICE_ETHERNET, 0, eth_receiver );
// get hardware address
204,7 → 206,7
return EOK;
}
 
eth_proto_ref eth_proccess_packet( packet_t packet ){
eth_proto_ref eth_proccess_packet( int dummy, packet_t packet ){
ERROR_DECLARE;
 
eth_header_ex_ref header;
215,6 → 217,9
eth_fcs_ref fcs;
 
length = packet_get_data_length( packet );
if( dummy ){
packet_trim( packet, sizeof( eth_preamble_t ), 0 );
}
if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_SUFFIX ) return NULL;
header = ( eth_header_ex_ref ) packet_get_data( packet );
type = ntohs( header->header.ethertype );
246,9 → 251,10
// invalid length/type, should not occurr
return NULL;
}
// TODO compute crc with fcs to erase?
if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ntohl( * fcs )){
return NULL;
if( dummy ){
if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ntohl( * fcs )){
return NULL;
}
}
if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR ))
|| ERROR_OCCURRED( packet_trim( packet, prefix, suffix ))){
260,11 → 266,21
int eth_receive_message( device_id_t device_id, packet_t packet ){
eth_proto_ref proto;
packet_t next;
eth_device_ref device;
int dummy;
 
rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
dummy = device->dummy;
rwlock_read_unlock( & eth_globals.devices_lock );
rwlock_read_lock( & eth_globals.protos_lock );
do{
next = pq_detach( packet );
proto = eth_proccess_packet( packet );
proto = eth_proccess_packet( dummy, packet );
if( proto ){
async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet ));
}else{
347,7 → 363,7
return EOK;
}
 
int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype ){
int eth_prepare_packet( int dummy, packet_t packet, uint8_t * src_addr, int ethertype ){
eth_header_ex_ref header;
eth_fcs_ref fcs;
uint8_t * src;
355,11 → 371,16
int length;
int i;
void * padding;
eth_preamble_ref preamble;
 
if( dummy ){
preamble = PACKET_PREFIX( packet, eth_preamble_t );
if( ! preamble ) return ENOMEM;
for( i = 0; i < 7; ++ i ) preamble->preamble[ i ] = ETH_PREAMBLE;
preamble->sfd = ETH_SFD;
}
header = PACKET_PREFIX( packet, eth_header_ex_t );
if( ! header ) return ENOMEM;
for( i = 0; i < 7; ++ i ) header->header.preamble[ i ] = ETH_PREAMBLE;
header->header.sfd = ETH_SFD;
length = packet_get_addr( packet, & src, & dest );
if( length < 0 ) return length;
if( length < ETH_ADDR ) return EINVAL;
378,9 → 399,11
header->lsap.ctrl = 0;
for( i = 0; i < 3; ++ i ) header->snap.proto[ i ] = 0;
header->snap.ethertype = ethertype;
fcs = PACKET_SUFFIX( packet, eth_fcs_t );
if( ! fcs ) return ENOMEM;
* fcs = htonl( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 ));
if( dummy ){
fcs = PACKET_SUFFIX( packet, eth_fcs_t );
if( ! fcs ) return ENOMEM;
* fcs = htonl( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 ));
}
return EOK;
}
 
406,7 → 429,7
// proccess packet queue
next = packet;
do{
if( ERROR_OCCURRED( eth_prepare_packet( next, ( uint8_t * ) device->addr->value, ethertype ))){
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 ));