Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4242 → Rev 4243

/branches/network/uspace/srv/net/nil/eth/eth.c
52,7 → 52,8
#include "../../include/ethernet_lsap.h"
#include "../../include/ethernet_protocols.h"
#include "../../include/protocol_map.h"
#include "../../netif/device.h"
#include "../../include/device.h"
#include "../../include/netif_messages.h"
 
#include "../../structures/measured_strings.h"
#include "../../structures/packet/packet.h"
67,6 → 68,8
#define ETH_SUFFIX sizeof( eth_fcs_t )
#define ETH_MAX_CONTENT 1500
#define ETH_MIN_CONTENT 46
#define ETH_MAX_TAGGED_CONTENT ( ETH_MAX_CONTENT - sizeof( eth_header_lsap_t ) - sizeof( eth_header_snap_t ))
#define ETH_MIN_TAGGED_CONTENT ( ETH_MIN_CONTENT - sizeof( eth_header_lsap_t ) - sizeof( eth_header_snap_t ))
 
/** Returns the device identifier message parameter.
*/
84,9 → 87,9
 
/** Returns the device driver service message parameter.
*/
#define IPC_GET_SERVICE( call ) ( services_t ) IPC_GET_ARG2( * call )
#define IPC_GET_SERVICE( call ) ( services_t ) IPC_GET_ARG3( * call )
 
#define IPC_GET_MTU( call ) ( size_t ) IPC_GET_ARG3( * call )
#define IPC_GET_MTU( call ) ( size_t ) IPC_GET_ARG2( * call )
 
#define IPC_GET_PHONE( call ) ( int ) IPC_GET_ARG5( * call )
 
123,7 → 126,6
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address );
int eth_register_message( services_t service, int phone );
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_process_packet( int dummy, packet_t packet );
int eth_prepare_packet( int dummy, packet_t packet, uint8_t * src_addr, int ethertype );
150,10 → 152,7
int eth_device_message( device_id_t device_id, services_t service, size_t mtu ){
ERROR_DECLARE;
 
aid_t message;
ipc_call_t answer;
eth_device_ref device;
ipcarg_t result;
int index;
 
rwlock_write_lock( & eth_globals.devices_lock );
175,7 → 174,7
if( ! device ) return ENOMEM;
device->device_id = device_id;
device->service = service;
device->mtu = ( mtu > 0 ) ? mtu : ETH_MAX_CONTENT;
device->mtu = (( mtu > 0 ) && ( mtu <= ETH_MAX_TAGGED_CONTENT )) ? mtu : ETH_MAX_TAGGED_CONTENT;
// TODO get dummy setting
device->dummy = 0;
// bind the device driver
186,21 → 185,11
return device->phone;
}
// get hardware address
message = async_send_1( device->phone, NET_NETIF_GET_ADDR, device->device_id, & answer );
if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->addr, & device->addr_data, 1 ))){
if( ERROR_OCCURRED( netif_get_addr( device->phone, device->device_id, & device->addr, & device->addr_data ))){
rwlock_write_unlock( & eth_globals.devices_lock );
free( device );
async_wait_for( message, NULL );
return ERROR_CODE;
}
async_wait_for( message, & result );
if( ERROR_OCCURRED( result )){
rwlock_write_unlock( & eth_globals.devices_lock );
free( device->addr );
free( device->addr_data );
free( device );
return ERROR_CODE;
}
// add to the cache
index = eth_devices_add( & eth_globals.devices, device->device_id, device );
if( index < 0 ){
248,7 → 237,7
// IEEE 802.3 + 802.2 + LSAP + SNAP
// organization code not supported
type = ntohs( header->snap.ethertype );
prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t) + sizeof( eth_header_snap_t);
prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t );
}else{
// IEEE 802.3 + 802.2 LSAP
type = lsap_map( header->lsap.dsap );
313,7 → 302,7
rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
* content = ( ETH_MAX_CONTENT > device->mtu ) ? device->mtu : ETH_MAX_CONTENT;
* content = device->mtu;
rwlock_read_unlock( & eth_globals.devices_lock );
* addr_len = ETH_ADDR;
* prefix = ETH_PREFIX;
384,6 → 373,13
void * padding;
eth_preamble_ref preamble;
 
length = packet_get_data_length( packet );
if( length > ETH_MAX_TAGGED_CONTENT ) return EINVAL;
if( length < ETH_MIN_TAGGED_CONTENT ){
padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT - length );
if( ! padding ) return ENOMEM;
bzero( padding, ETH_MIN_TAGGED_CONTENT - length );
}
if( dummy ){
preamble = PACKET_PREFIX( packet, eth_preamble_t );
if( ! preamble ) return ENOMEM;
392,24 → 388,17
}
header = PACKET_PREFIX( packet, eth_header_ex_t );
if( ! header ) return ENOMEM;
length = packet_get_addr( packet, & src, & dest );
if( length < 0 ) return length;
if( length < ETH_ADDR ) return EINVAL;
memcpy( header->header.src, src_addr, ETH_ADDR );
memcpy( & header->header.dest, dest, ETH_ADDR );
length = packet_get_data_length( packet );
if( length > ETH_MAX_CONTENT ) return EINVAL;
if( length < ETH_MIN_CONTENT ){
padding = packet_suffix( packet, ETH_MIN_CONTENT - length );
if( ! padding ) return ENOMEM;
bzero( padding, ETH_MIN_CONTENT - length );
}
header->header.ethertype = htons( length );
header->header.ethertype = htons( length + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t ));
header->lsap.dsap = 0xAA;
header->lsap.ssap = header->lsap.dsap;
header->lsap.ctrl = 0;
for( i = 0; i < 3; ++ i ) header->snap.proto[ i ] = 0;
header->snap.ethertype = ethertype;
length = packet_get_addr( packet, & src, & dest );
if( length < 0 ) return length;
if( length < ETH_ADDR ) return EINVAL;
memcpy( header->header.src, src_addr, ETH_ADDR );
memcpy( header->header.dest, dest, ETH_ADDR );
if( dummy ){
fcs = PACKET_SUFFIX( packet, eth_fcs_t );
if( ! fcs ) return ENOMEM;
450,7 → 439,7
}
}while( next );
// send packet queue
async_msg_2( device->phone, NET_NETIF_SEND, device_id, packet_get_id( packet ));
netif_send_msg( device->phone, device_id, packet );
rwlock_read_unlock( & eth_globals.devices_lock );
return EOK;
}
461,6 → 450,7
measured_string_ref address;
packet_t packet;
 
// printf( "\nmessage %d - %d", IPC_GET_METHOD( * call ), NET_NIL_FIRST );
* answer_count = 0;
switch( IPC_GET_METHOD( * call )){
case IPC_M_PHONE_HUNGUP:
480,7 → 470,6
case NET_NIL_BROADCAST_ADDR:
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 ));
}