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,10 → 251,11 |
// invalid length/type, should not occurr |
return NULL; |
} |
// TODO compute crc with fcs to erase? |
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 ))){ |
return NULL; |
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; |
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 )); |