66,14 → 66,36 |
#include "eth.h" |
#include "eth_header.h" |
|
/** Reserved packet prefix length. |
*/ |
#define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t )) |
|
/** Reserved packet suffix length. |
*/ |
#define ETH_SUFFIX sizeof( eth_fcs_t ) |
|
/** Maximum packet content length. |
*/ |
#define ETH_MAX_CONTENT 1500 |
|
/** Minimum packet content length. |
*/ |
#define ETH_MIN_CONTENT 46 |
|
/** Maximum tagged packet content length. |
*/ |
#define ETH_MAX_TAGGED_CONTENT( flags ) ( ETH_MAX_CONTENT - (( IS_8023_2_LSAP( flags ) || IS_8023_2_SNAP( flags )) ? sizeof( eth_header_lsap_t ) : 0 ) - ( IS_8023_2_SNAP( flags ) ? sizeof( eth_header_snap_t ) : 0 )) |
|
/** Minimum tagged packet content length. |
*/ |
#define ETH_MIN_TAGGED_CONTENT( flags ) ( ETH_MIN_CONTENT - (( IS_8023_2_LSAP( flags ) || IS_8023_2_SNAP( flags )) ? sizeof( eth_header_lsap_t ) : 0 ) - ( IS_8023_2_SNAP( flags ) ? sizeof( eth_header_snap_t ) : 0 )) |
|
/** Dummy flag shift value. |
*/ |
#define ETH_DUMMY_SHIFT 0 |
|
/** Mode flag shift value. |
*/ |
#define ETH_MODE_SHIFT 1 |
|
/** Dummy device flag. |
80,6 → 102,10 |
* Preamble and FCS are mandatory part of the packets. |
*/ |
#define ETH_DUMMY ( 1 << ETH_DUMMY_SHIFT ) |
|
/** Returns the dummy flag. |
* @see ETH_DUMMY |
*/ |
#define IS_DUMMY( flags ) (( flags ) & ETH_DUMMY ) |
|
/** Device mode flags. |
88,22 → 114,59 |
* @see ETH_8023_2_SNAP |
*/ |
#define ETH_MODE_MASK ( 3 << ETH_MODE_SHIFT ) |
|
/** DIX Ethernet mode flag. |
*/ |
#define ETH_DIX ( 1 << ETH_MODE_SHIFT ) |
|
/** Returns whether the DIX Ethernet mode flag is set. |
* @param flags The ethernet flags. Input parameter. |
* @see ETH_DIX |
*/ |
#define IS_DIX( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_DIX ) |
|
/** 802.3 + 802.2 + LSAP mode flag. |
*/ |
#define ETH_8023_2_LSAP ( 2 << ETH_MODE_SHIFT ) |
|
/** Returns whether the 802.3 + 802.2 + LSAP mode flag is set. |
* @param flags The ethernet flags. Input parameter. |
* @see ETH_8023_2_LSAP |
*/ |
#define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP ) |
|
/** 802.3 + 802.2 + LSAP + SNAP mode flag. |
*/ |
#define ETH_8023_2_SNAP ( 3 << ETH_MODE_SHIFT ) |
|
/** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. |
* @param flags The ethernet flags. Input parameter. |
* @see ETH_8023_2_SNAP |
*/ |
#define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP ) |
|
/** Type definition of the ethernet address type. |
* @see eth_addr_type |
*/ |
typedef enum eth_addr_type eth_addr_type_t; |
|
/** Type definition of the ethernet address type pointer. |
* @see eth_addr_type |
*/ |
typedef eth_addr_type_t * eth_addr_type_ref; |
|
/** Ethernet address type. |
*/ |
enum eth_addr_type{ |
/** Local address. |
*/ |
ETH_LOCAL_ADDR, |
/** Broadcast address. |
*/ |
ETH_BROADCAST_ADDR |
}; |
|
/** Ethernet global data. |
/** Ethernet module global data. |
*/ |
eth_globals_t eth_globals; |
|
113,19 → 176,92 |
*/ |
void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
|
DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) |
/** Registers new device or updates the MTU of an existing one. |
* Determines the device local hardware address. |
* @param device_id The new device identifier. Input parameter. |
* @param service The device driver service. Input parameter. |
* @param mtu The device maximum transmission unit. Input parameter. |
* @returns EOK on success. |
* @returns EEXIST if the device with the different service exists. |
* @returns ENOMEM if there is not enough memory left. |
* @returns Other error codes as defined for the net_get_device_conf_req() function. |
* @returns Other error codes as defined for the netif_bind_service() function. |
* @returns Other error codes as defined for the netif_get_addr() function. |
*/ |
int eth_device_message( device_id_t device_id, services_t service, size_t mtu ); |
|
INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) |
/** Registers receiving module service. |
* Passes received packets for this service. |
* @param service The module service. Input parameter. |
* @param phone The service phone. Input parameter. |
* @returns EOK on success. |
* @returns ENOENT if the service is not known. |
* @returns ENOMEM if there is not enough memory left. |
*/ |
int nil_register_message( services_t service, int phone ); |
|
int eth_device_message( device_id_t device_id, services_t service, size_t mtu ); |
int nil_receive_msg( int nil_phone, device_id_t device_id, packet_t packet ); |
int nil_register_message( services_t service, int phone ); |
/** Returns the device packet dimensions for sending. |
* @param device_id The device identifier. Input parameter. |
* @param addr_len The minimum reserved address length. Output parameter. |
* @param prefix The minimum reserved prefix size. Output parameter. |
* @param content The maximum content size. Output parameter. |
* @param suffix The minimum reserved suffix size. Output parameter. |
* @returns EOK on success. |
* @returns EBADMEM if either one of the parameters is NULL. |
* @returns ENOENT if there is no such device. |
*/ |
int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); |
|
/** Returns the device hardware address. |
* @param device_id The device identifier. Input parameter. |
* @param type Type of the desired address. Input parameter |
* @param address The device hardware address. Output parameter. |
* @returns EOK on success. |
* @returns EBADMEM if the address parameter is NULL. |
* @returns ENOENT if there no such device. |
*/ |
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ); |
|
/** Sends the packet queue. |
* Sends only packet successfully processed by the eth_prepare_packet() function. |
* @param device_id The device identifier. Input parameter. |
* @param packet The packet queue. Input parameter. |
* @param sender The sending module service. Input parameter. |
* @returns EOK on success. |
* @returns ENOENT if there no such device. |
* @returns EINVAL if the service parameter is not known. |
*/ |
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
|
/** Processes the received packet and chooses the target registered module. |
* @param flags The device flags. Input parameter. |
* @param packet The packet. Input parameter. |
* @returns The target registered module. |
* @returns NULL if the packet is not long enough. |
* @returns NULL if the packet is too long. |
* @returns NULL if the raw ethernet protocol is used. |
* @returns NULL if the dummy device FCS checksum is invalid. |
* @returns NULL if the packet address length is not big enough. |
*/ |
eth_proto_ref eth_process_packet( int flags, packet_t packet ); |
|
/** Prepares the packet for sending. |
* @param flags The device flags. Input parameter. |
* @param packet The packet. Input parameter. |
* @param src_addr The source hardware address. Input parameter. |
* @param ethertype The ethernet protocol type. Input parameter. |
* @param mtu The device maximum transmission unit. Input parameter. |
* @returns EOK on success. |
* @returns EINVAL if the packet addresses length is not long enough. |
* @returns EINVAL if the packet is bigger than the device MTU. |
* @returns ENOMEM if there is not enough memory in the packet. |
*/ |
int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype ); |
|
DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) |
|
INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) |
|
int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){ |
int index; |
eth_proto_ref proto; |
331,7 → 467,7 |
int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ |
eth_device_ref device; |
|
if( !( addr_len && prefix && content && suffix )) return EINVAL; |
if( !( addr_len && prefix && content && suffix )) return EBADMEM; |
rwlock_read_lock( & eth_globals.devices_lock ); |
device = eth_devices_find( & eth_globals.devices, device_id ); |
if( ! device ){ |
349,7 → 485,7 |
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){ |
eth_device_ref device; |
|
if( ! address ) return EINVAL; |
if( ! address ) return EBADMEM; |
if( type == ETH_BROADCAST_ADDR ){ |
* address = eth_globals.broadcast_addr; |
}else{ |
414,6 → 550,7 |
if( length < 0 ) return length; |
if( length < ETH_ADDR ) return EINVAL; |
length = packet_get_data_length( packet ); |
//TODO smaller than MTU! |
if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL; |
if( length < ETH_MIN_TAGGED_CONTENT( flags )){ |
padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |