Rev 4332 | Rev 4351 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4332 | Rev 4350 | ||
|---|---|---|---|
| Line 64... | Line 64... | ||
| 64 | #include "../nil_module.h" |
64 | #include "../nil_module.h" |
| 65 | 65 | ||
| 66 | #include "eth.h" |
66 | #include "eth.h" |
| 67 | #include "eth_header.h" |
67 | #include "eth_header.h" |
| 68 | 68 | ||
| - | 69 | /** Reserved packet prefix length. |
|
| - | 70 | */ |
|
| 69 | #define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t )) |
71 | #define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t )) |
| - | 72 | ||
| - | 73 | /** Reserved packet suffix length. |
|
| - | 74 | */ |
|
| 70 | #define ETH_SUFFIX sizeof( eth_fcs_t ) |
75 | #define ETH_SUFFIX sizeof( eth_fcs_t ) |
| - | 76 | ||
| - | 77 | /** Maximum packet content length. |
|
| - | 78 | */ |
|
| 71 | #define ETH_MAX_CONTENT 1500 |
79 | #define ETH_MAX_CONTENT 1500 |
| - | 80 | ||
| - | 81 | /** Minimum packet content length. |
|
| - | 82 | */ |
|
| 72 | #define ETH_MIN_CONTENT 46 |
83 | #define ETH_MIN_CONTENT 46 |
| - | 84 | ||
| - | 85 | /** Maximum tagged packet content length. |
|
| - | 86 | */ |
|
| 73 | #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 )) |
87 | #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 )) |
| - | 88 | ||
| - | 89 | /** Minimum tagged packet content length. |
|
| - | 90 | */ |
|
| 74 | #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 )) |
91 | #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 )) |
| 75 | 92 | ||
| - | 93 | /** Dummy flag shift value. |
|
| - | 94 | */ |
|
| 76 | #define ETH_DUMMY_SHIFT 0 |
95 | #define ETH_DUMMY_SHIFT 0 |
| - | 96 | ||
| - | 97 | /** Mode flag shift value. |
|
| - | 98 | */ |
|
| 77 | #define ETH_MODE_SHIFT 1 |
99 | #define ETH_MODE_SHIFT 1 |
| 78 | 100 | ||
| 79 | /** Dummy device flag. |
101 | /** Dummy device flag. |
| 80 | * Preamble and FCS are mandatory part of the packets. |
102 | * Preamble and FCS are mandatory part of the packets. |
| 81 | */ |
103 | */ |
| 82 | #define ETH_DUMMY ( 1 << ETH_DUMMY_SHIFT ) |
104 | #define ETH_DUMMY ( 1 << ETH_DUMMY_SHIFT ) |
| - | 105 | ||
| - | 106 | /** Returns the dummy flag. |
|
| - | 107 | * @see ETH_DUMMY |
|
| - | 108 | */ |
|
| 83 | #define IS_DUMMY( flags ) (( flags ) & ETH_DUMMY ) |
109 | #define IS_DUMMY( flags ) (( flags ) & ETH_DUMMY ) |
| 84 | 110 | ||
| 85 | /** Device mode flags. |
111 | /** Device mode flags. |
| 86 | * @see ETH_DIX |
112 | * @see ETH_DIX |
| 87 | * @see ETH_8023_2_LSAP |
113 | * @see ETH_8023_2_LSAP |
| 88 | * @see ETH_8023_2_SNAP |
114 | * @see ETH_8023_2_SNAP |
| 89 | */ |
115 | */ |
| 90 | #define ETH_MODE_MASK ( 3 << ETH_MODE_SHIFT ) |
116 | #define ETH_MODE_MASK ( 3 << ETH_MODE_SHIFT ) |
| - | 117 | ||
| - | 118 | /** DIX Ethernet mode flag. |
|
| - | 119 | */ |
|
| 91 | #define ETH_DIX ( 1 << ETH_MODE_SHIFT ) |
120 | #define ETH_DIX ( 1 << ETH_MODE_SHIFT ) |
| - | 121 | ||
| - | 122 | /** Returns whether the DIX Ethernet mode flag is set. |
|
| - | 123 | * @param flags The ethernet flags. Input parameter. |
|
| - | 124 | * @see ETH_DIX |
|
| - | 125 | */ |
|
| 92 | #define IS_DIX( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_DIX ) |
126 | #define IS_DIX( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_DIX ) |
| - | 127 | ||
| - | 128 | /** 802.3 + 802.2 + LSAP mode flag. |
|
| - | 129 | */ |
|
| 93 | #define ETH_8023_2_LSAP ( 2 << ETH_MODE_SHIFT ) |
130 | #define ETH_8023_2_LSAP ( 2 << ETH_MODE_SHIFT ) |
| - | 131 | ||
| - | 132 | /** Returns whether the 802.3 + 802.2 + LSAP mode flag is set. |
|
| - | 133 | * @param flags The ethernet flags. Input parameter. |
|
| - | 134 | * @see ETH_8023_2_LSAP |
|
| - | 135 | */ |
|
| 94 | #define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP ) |
136 | #define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP ) |
| - | 137 | ||
| - | 138 | /** 802.3 + 802.2 + LSAP + SNAP mode flag. |
|
| - | 139 | */ |
|
| 95 | #define ETH_8023_2_SNAP ( 3 << ETH_MODE_SHIFT ) |
140 | #define ETH_8023_2_SNAP ( 3 << ETH_MODE_SHIFT ) |
| - | 141 | ||
| - | 142 | /** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. |
|
| - | 143 | * @param flags The ethernet flags. Input parameter. |
|
| - | 144 | * @see ETH_8023_2_SNAP |
|
| - | 145 | */ |
|
| 96 | #define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP ) |
146 | #define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP ) |
| 97 | 147 | ||
| - | 148 | /** Type definition of the ethernet address type. |
|
| - | 149 | * @see eth_addr_type |
|
| - | 150 | */ |
|
| 98 | typedef enum eth_addr_type eth_addr_type_t; |
151 | typedef enum eth_addr_type eth_addr_type_t; |
| - | 152 | ||
| - | 153 | /** Type definition of the ethernet address type pointer. |
|
| - | 154 | * @see eth_addr_type |
|
| - | 155 | */ |
|
| 99 | typedef eth_addr_type_t * eth_addr_type_ref; |
156 | typedef eth_addr_type_t * eth_addr_type_ref; |
| 100 | 157 | ||
| - | 158 | /** Ethernet address type. |
|
| - | 159 | */ |
|
| 101 | enum eth_addr_type{ |
160 | enum eth_addr_type{ |
| - | 161 | /** Local address. |
|
| - | 162 | */ |
|
| 102 | ETH_LOCAL_ADDR, |
163 | ETH_LOCAL_ADDR, |
| - | 164 | /** Broadcast address. |
|
| - | 165 | */ |
|
| 103 | ETH_BROADCAST_ADDR |
166 | ETH_BROADCAST_ADDR |
| 104 | }; |
167 | }; |
| 105 | 168 | ||
| 106 | /** Ethernet global data. |
169 | /** Ethernet module global data. |
| 107 | */ |
170 | */ |
| 108 | eth_globals_t eth_globals; |
171 | eth_globals_t eth_globals; |
| 109 | 172 | ||
| 110 | /** Processes IPC messages from the registered device driver modules in an infinite loop. |
173 | /** Processes IPC messages from the registered device driver modules in an infinite loop. |
| 111 | * @param iid The message identifier. Input parameter. |
174 | * @param iid The message identifier. Input parameter. |
| 112 | * @param icall The message parameters. Input/output parameter. |
175 | * @param icall The message parameters. Input/output parameter. |
| 113 | */ |
176 | */ |
| 114 | void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
177 | void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
| 115 | 178 | ||
| - | 179 | /** Registers new device or updates the MTU of an existing one. |
|
| - | 180 | * Determines the device local hardware address. |
|
| - | 181 | * @param device_id The new device identifier. Input parameter. |
|
| - | 182 | * @param service The device driver service. Input parameter. |
|
| - | 183 | * @param mtu The device maximum transmission unit. Input parameter. |
|
| - | 184 | * @returns EOK on success. |
|
| 116 | DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) |
185 | * @returns EEXIST if the device with the different service exists. |
| 117 | - | ||
| 118 | INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) |
186 | * @returns ENOMEM if there is not enough memory left. |
| - | 187 | * @returns Other error codes as defined for the net_get_device_conf_req() function. |
|
| - | 188 | * @returns Other error codes as defined for the netif_bind_service() function. |
|
| - | 189 | * @returns Other error codes as defined for the netif_get_addr() function. |
|
| 119 | 190 | */ |
|
| 120 | int eth_device_message( device_id_t device_id, services_t service, size_t mtu ); |
191 | int eth_device_message( device_id_t device_id, services_t service, size_t mtu ); |
| - | 192 | ||
| - | 193 | /** Registers receiving module service. |
|
| - | 194 | * Passes received packets for this service. |
|
| 121 | int nil_receive_msg( int nil_phone, device_id_t device_id, packet_t packet ); |
195 | * @param service The module service. Input parameter. |
| - | 196 | * @param phone The service phone. Input parameter. |
|
| - | 197 | * @returns EOK on success. |
|
| - | 198 | * @returns ENOENT if the service is not known. |
|
| - | 199 | * @returns ENOMEM if there is not enough memory left. |
|
| - | 200 | */ |
|
| 122 | int nil_register_message( services_t service, int phone ); |
201 | int nil_register_message( services_t service, int phone ); |
| - | 202 | ||
| - | 203 | /** Returns the device packet dimensions for sending. |
|
| - | 204 | * @param device_id The device identifier. Input parameter. |
|
| - | 205 | * @param addr_len The minimum reserved address length. Output parameter. |
|
| - | 206 | * @param prefix The minimum reserved prefix size. Output parameter. |
|
| - | 207 | * @param content The maximum content size. Output parameter. |
|
| - | 208 | * @param suffix The minimum reserved suffix size. Output parameter. |
|
| - | 209 | * @returns EOK on success. |
|
| - | 210 | * @returns EBADMEM if either one of the parameters is NULL. |
|
| - | 211 | * @returns ENOENT if there is no such device. |
|
| - | 212 | */ |
|
| 123 | int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); |
213 | int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); |
| - | 214 | ||
| - | 215 | /** Returns the device hardware address. |
|
| - | 216 | * @param device_id The device identifier. Input parameter. |
|
| - | 217 | * @param type Type of the desired address. Input parameter |
|
| - | 218 | * @param address The device hardware address. Output parameter. |
|
| - | 219 | * @returns EOK on success. |
|
| - | 220 | * @returns EBADMEM if the address parameter is NULL. |
|
| - | 221 | * @returns ENOENT if there no such device. |
|
| - | 222 | */ |
|
| 124 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ); |
223 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ); |
| - | 224 | ||
| - | 225 | /** Sends the packet queue. |
|
| - | 226 | * Sends only packet successfully processed by the eth_prepare_packet() function. |
|
| - | 227 | * @param device_id The device identifier. Input parameter. |
|
| - | 228 | * @param packet The packet queue. Input parameter. |
|
| - | 229 | * @param sender The sending module service. Input parameter. |
|
| - | 230 | * @returns EOK on success. |
|
| - | 231 | * @returns ENOENT if there no such device. |
|
| - | 232 | * @returns EINVAL if the service parameter is not known. |
|
| - | 233 | */ |
|
| 125 | int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
234 | int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
| - | 235 | ||
| - | 236 | /** Processes the received packet and chooses the target registered module. |
|
| - | 237 | * @param flags The device flags. Input parameter. |
|
| - | 238 | * @param packet The packet. Input parameter. |
|
| - | 239 | * @returns The target registered module. |
|
| - | 240 | * @returns NULL if the packet is not long enough. |
|
| - | 241 | * @returns NULL if the packet is too long. |
|
| - | 242 | * @returns NULL if the raw ethernet protocol is used. |
|
| - | 243 | * @returns NULL if the dummy device FCS checksum is invalid. |
|
| - | 244 | * @returns NULL if the packet address length is not big enough. |
|
| - | 245 | */ |
|
| 126 | eth_proto_ref eth_process_packet( int flags, packet_t packet ); |
246 | eth_proto_ref eth_process_packet( int flags, packet_t packet ); |
| - | 247 | ||
| - | 248 | /** Prepares the packet for sending. |
|
| - | 249 | * @param flags The device flags. Input parameter. |
|
| - | 250 | * @param packet The packet. Input parameter. |
|
| - | 251 | * @param src_addr The source hardware address. Input parameter. |
|
| - | 252 | * @param ethertype The ethernet protocol type. Input parameter. |
|
| - | 253 | * @param mtu The device maximum transmission unit. Input parameter. |
|
| - | 254 | * @returns EOK on success. |
|
| - | 255 | * @returns EINVAL if the packet addresses length is not long enough. |
|
| - | 256 | * @returns EINVAL if the packet is bigger than the device MTU. |
|
| - | 257 | * @returns ENOMEM if there is not enough memory in the packet. |
|
| - | 258 | */ |
|
| 127 | int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype ); |
259 | int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype ); |
| 128 | 260 | ||
| - | 261 | DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) |
|
| - | 262 | ||
| - | 263 | INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) |
|
| - | 264 | ||
| 129 | int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){ |
265 | int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){ |
| 130 | int index; |
266 | int index; |
| 131 | eth_proto_ref proto; |
267 | eth_proto_ref proto; |
| 132 | 268 | ||
| 133 | //TODO clear device if off? |
269 | //TODO clear device if off? |
| Line 329... | Line 465... | ||
| 329 | } |
465 | } |
| 330 | 466 | ||
| 331 | int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ |
467 | int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ |
| 332 | eth_device_ref device; |
468 | eth_device_ref device; |
| 333 | 469 | ||
| 334 | if( !( addr_len && prefix && content && suffix )) return EINVAL; |
470 | if( !( addr_len && prefix && content && suffix )) return EBADMEM; |
| 335 | rwlock_read_lock( & eth_globals.devices_lock ); |
471 | rwlock_read_lock( & eth_globals.devices_lock ); |
| 336 | device = eth_devices_find( & eth_globals.devices, device_id ); |
472 | device = eth_devices_find( & eth_globals.devices, device_id ); |
| 337 | if( ! device ){ |
473 | if( ! device ){ |
| 338 | rwlock_read_unlock( & eth_globals.devices_lock ); |
474 | rwlock_read_unlock( & eth_globals.devices_lock ); |
| 339 | return ENOENT; |
475 | return ENOENT; |
| Line 347... | Line 483... | ||
| 347 | } |
483 | } |
| 348 | 484 | ||
| 349 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){ |
485 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){ |
| 350 | eth_device_ref device; |
486 | eth_device_ref device; |
| 351 | 487 | ||
| 352 | if( ! address ) return EINVAL; |
488 | if( ! address ) return EBADMEM; |
| 353 | if( type == ETH_BROADCAST_ADDR ){ |
489 | if( type == ETH_BROADCAST_ADDR ){ |
| 354 | * address = eth_globals.broadcast_addr; |
490 | * address = eth_globals.broadcast_addr; |
| 355 | }else{ |
491 | }else{ |
| 356 | rwlock_read_lock( & eth_globals.devices_lock ); |
492 | rwlock_read_lock( & eth_globals.devices_lock ); |
| 357 | device = eth_devices_find( & eth_globals.devices, device_id ); |
493 | device = eth_devices_find( & eth_globals.devices, device_id ); |
| Line 412... | Line 548... | ||
| 412 | 548 | ||
| 413 | length = packet_get_addr( packet, & src, & dest ); |
549 | length = packet_get_addr( packet, & src, & dest ); |
| 414 | if( length < 0 ) return length; |
550 | if( length < 0 ) return length; |
| 415 | if( length < ETH_ADDR ) return EINVAL; |
551 | if( length < ETH_ADDR ) return EINVAL; |
| 416 | length = packet_get_data_length( packet ); |
552 | length = packet_get_data_length( packet ); |
| - | 553 | //TODO smaller than MTU! |
|
| 417 | if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL; |
554 | if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL; |
| 418 | if( length < ETH_MIN_TAGGED_CONTENT( flags )){ |
555 | if( length < ETH_MIN_TAGGED_CONTENT( flags )){ |
| 419 | padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
556 | padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
| 420 | if( ! padding ) return ENOMEM; |
557 | if( ! padding ) return ENOMEM; |
| 421 | bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
558 | bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |