Rev 4077 | Rev 4163 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4077 | Rev 4153 | ||
|---|---|---|---|
| Line 121... | Line 121... | ||
| 121 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ); |
121 | int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ); |
| 122 | int eth_register_message( services_t service, int phone ); |
122 | int eth_register_message( services_t service, int phone ); |
| 123 | int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
123 | int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); |
| 124 | int eth_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ); |
124 | int eth_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ); |
| 125 | void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
125 | void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); |
| 126 | eth_proto_ref eth_proccess_packet( packet_t packet ); |
126 | eth_proto_ref eth_proccess_packet( int dummy, packet_t packet ); |
| 127 | int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype ); |
127 | int eth_prepare_packet( int dummy, packet_t packet, uint8_t * src_addr, int ethertype ); |
| 128 | 128 | ||
| 129 | int eth_initialize( void ){ |
129 | int eth_initialize( void ){ |
| 130 | ERROR_DECLARE; |
130 | ERROR_DECLARE; |
| 131 | 131 | ||
| 132 | rwlock_initialize( & eth_globals.devices_lock ); |
132 | rwlock_initialize( & eth_globals.devices_lock ); |
| Line 171... | Line 171... | ||
| 171 | device = ( eth_device_ref ) malloc( sizeof( eth_device_t )); |
171 | device = ( eth_device_ref ) malloc( sizeof( eth_device_t )); |
| 172 | if( ! device ) return ENOMEM; |
172 | if( ! device ) return ENOMEM; |
| 173 | device->device_id = device_id; |
173 | device->device_id = device_id; |
| 174 | device->service = service; |
174 | device->service = service; |
| 175 | device->mtu = mtu; |
175 | device->mtu = mtu; |
| - | 176 | // TODO get dummy setting |
|
| - | 177 | device->dummy = 0; |
|
| 176 | // bind the device driver |
178 | // bind the device driver |
| 177 | device->phone = bind_service( device->service, device->device_id, SERVICE_ETHERNET, 0, eth_receiver ); |
179 | device->phone = bind_service( device->service, device->device_id, SERVICE_ETHERNET, 0, eth_receiver ); |
| 178 | // get hardware address |
180 | // get hardware address |
| 179 | message = async_send_1( device->phone, NET_NETIF_GET_ADDR, device->device_id, & answer ); |
181 | message = async_send_1( device->phone, NET_NETIF_GET_ADDR, device->device_id, & answer ); |
| 180 | if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->addr, & device->addr_data, 1 ))){ |
182 | if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->addr, & device->addr_data, 1 ))){ |
| Line 202... | Line 204... | ||
| 202 | } |
204 | } |
| 203 | rwlock_write_unlock( & eth_globals.devices_lock ); |
205 | rwlock_write_unlock( & eth_globals.devices_lock ); |
| 204 | return EOK; |
206 | return EOK; |
| 205 | } |
207 | } |
| 206 | 208 | ||
| 207 | eth_proto_ref eth_proccess_packet( packet_t packet ){ |
209 | eth_proto_ref eth_proccess_packet( int dummy, packet_t packet ){ |
| 208 | ERROR_DECLARE; |
210 | ERROR_DECLARE; |
| 209 | 211 | ||
| 210 | eth_header_ex_ref header; |
212 | eth_header_ex_ref header; |
| 211 | size_t length; |
213 | size_t length; |
| 212 | int type; |
214 | int type; |
| 213 | size_t prefix; |
215 | size_t prefix; |
| 214 | size_t suffix; |
216 | size_t suffix; |
| 215 | eth_fcs_ref fcs; |
217 | eth_fcs_ref fcs; |
| 216 | 218 | ||
| 217 | length = packet_get_data_length( packet ); |
219 | length = packet_get_data_length( packet ); |
| - | 220 | if( dummy ){ |
|
| - | 221 | packet_trim( packet, sizeof( eth_preamble_t ), 0 ); |
|
| - | 222 | } |
|
| 218 | if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_SUFFIX ) return NULL; |
223 | if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_SUFFIX ) return NULL; |
| 219 | header = ( eth_header_ex_ref ) packet_get_data( packet ); |
224 | header = ( eth_header_ex_ref ) packet_get_data( packet ); |
| 220 | type = ntohs( header->header.ethertype ); |
225 | type = ntohs( header->header.ethertype ); |
| 221 | if( type >= ETH_MIN_PROTO ){ |
226 | if( type >= ETH_MIN_PROTO ){ |
| 222 | // DIX Ethernet |
227 | // DIX Ethernet |
| Line 244... | Line 249... | ||
| 244 | suffix += length - prefix - type; |
249 | suffix += length - prefix - type; |
| 245 | }else{ |
250 | }else{ |
| 246 | // invalid length/type, should not occurr |
251 | // invalid length/type, should not occurr |
| 247 | return NULL; |
252 | return NULL; |
| 248 | } |
253 | } |
| 249 | // TODO compute crc with fcs to erase? |
254 | if( dummy ){ |
| 250 | if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ntohl( * fcs )){ |
255 | if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ntohl( * fcs )){ |
| 251 | return NULL; |
256 | return NULL; |
| - | 257 | } |
|
| 252 | } |
258 | } |
| 253 | if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR )) |
259 | if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR )) |
| 254 | || ERROR_OCCURRED( packet_trim( packet, prefix, suffix ))){ |
260 | || ERROR_OCCURRED( packet_trim( packet, prefix, suffix ))){ |
| 255 | return NULL; |
261 | return NULL; |
| 256 | } |
262 | } |
| Line 258... | Line 264... | ||
| 258 | } |
264 | } |
| 259 | 265 | ||
| 260 | int eth_receive_message( device_id_t device_id, packet_t packet ){ |
266 | int eth_receive_message( device_id_t device_id, packet_t packet ){ |
| 261 | eth_proto_ref proto; |
267 | eth_proto_ref proto; |
| 262 | packet_t next; |
268 | packet_t next; |
| - | 269 | eth_device_ref device; |
|
| - | 270 | int dummy; |
|
| 263 | 271 | ||
| - | 272 | rwlock_read_lock( & eth_globals.devices_lock ); |
|
| - | 273 | device = eth_devices_find( & eth_globals.devices, device_id ); |
|
| - | 274 | if( ! device ){ |
|
| - | 275 | rwlock_read_unlock( & eth_globals.devices_lock ); |
|
| - | 276 | return ENOENT; |
|
| - | 277 | } |
|
| - | 278 | dummy = device->dummy; |
|
| - | 279 | rwlock_read_unlock( & eth_globals.devices_lock ); |
|
| 264 | rwlock_read_lock( & eth_globals.protos_lock ); |
280 | rwlock_read_lock( & eth_globals.protos_lock ); |
| 265 | do{ |
281 | do{ |
| 266 | next = pq_detach( packet ); |
282 | next = pq_detach( packet ); |
| 267 | proto = eth_proccess_packet( packet ); |
283 | proto = eth_proccess_packet( dummy, packet ); |
| 268 | if( proto ){ |
284 | if( proto ){ |
| 269 | async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet )); |
285 | async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet )); |
| 270 | }else{ |
286 | }else{ |
| 271 | // drop invalid/unknown |
287 | // drop invalid/unknown |
| 272 | packet_release( eth_globals.networking_phone, packet_get_id( packet )); |
288 | packet_release( eth_globals.networking_phone, packet_get_id( packet )); |
| Line 345... | Line 361... | ||
| 345 | } |
361 | } |
| 346 | rwlock_write_unlock( & eth_globals.protos_lock ); |
362 | rwlock_write_unlock( & eth_globals.protos_lock ); |
| 347 | return EOK; |
363 | return EOK; |
| 348 | } |
364 | } |
| 349 | 365 | ||
| 350 | int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype ){ |
366 | int eth_prepare_packet( int dummy, packet_t packet, uint8_t * src_addr, int ethertype ){ |
| 351 | eth_header_ex_ref header; |
367 | eth_header_ex_ref header; |
| 352 | eth_fcs_ref fcs; |
368 | eth_fcs_ref fcs; |
| 353 | uint8_t * src; |
369 | uint8_t * src; |
| 354 | uint8_t * dest; |
370 | uint8_t * dest; |
| 355 | int length; |
371 | int length; |
| 356 | int i; |
372 | int i; |
| 357 | void * padding; |
373 | void * padding; |
| - | 374 | eth_preamble_ref preamble; |
|
| 358 | 375 | ||
| - | 376 | if( dummy ){ |
|
| - | 377 | preamble = PACKET_PREFIX( packet, eth_preamble_t ); |
|
| - | 378 | if( ! preamble ) return ENOMEM; |
|
| - | 379 | for( i = 0; i < 7; ++ i ) preamble->preamble[ i ] = ETH_PREAMBLE; |
|
| - | 380 | preamble->sfd = ETH_SFD; |
|
| - | 381 | } |
|
| 359 | header = PACKET_PREFIX( packet, eth_header_ex_t ); |
382 | header = PACKET_PREFIX( packet, eth_header_ex_t ); |
| 360 | if( ! header ) return ENOMEM; |
383 | if( ! header ) return ENOMEM; |
| 361 | for( i = 0; i < 7; ++ i ) header->header.preamble[ i ] = ETH_PREAMBLE; |
- | |
| 362 | header->header.sfd = ETH_SFD; |
- | |
| 363 | length = packet_get_addr( packet, & src, & dest ); |
384 | length = packet_get_addr( packet, & src, & dest ); |
| 364 | if( length < 0 ) return length; |
385 | if( length < 0 ) return length; |
| 365 | if( length < ETH_ADDR ) return EINVAL; |
386 | if( length < ETH_ADDR ) return EINVAL; |
| 366 | memcpy( header->header.src, src_addr, ETH_ADDR ); |
387 | memcpy( header->header.src, src_addr, ETH_ADDR ); |
| 367 | memcpy( & header->header.dest, dest, ETH_ADDR ); |
388 | memcpy( & header->header.dest, dest, ETH_ADDR ); |
| Line 376... | Line 397... | ||
| 376 | header->lsap.dsap = 0xAA; |
397 | header->lsap.dsap = 0xAA; |
| 377 | header->lsap.ssap = header->lsap.dsap; |
398 | header->lsap.ssap = header->lsap.dsap; |
| 378 | header->lsap.ctrl = 0; |
399 | header->lsap.ctrl = 0; |
| 379 | for( i = 0; i < 3; ++ i ) header->snap.proto[ i ] = 0; |
400 | for( i = 0; i < 3; ++ i ) header->snap.proto[ i ] = 0; |
| 380 | header->snap.ethertype = ethertype; |
401 | header->snap.ethertype = ethertype; |
| - | 402 | if( dummy ){ |
|
| 381 | fcs = PACKET_SUFFIX( packet, eth_fcs_t ); |
403 | fcs = PACKET_SUFFIX( packet, eth_fcs_t ); |
| 382 | if( ! fcs ) return ENOMEM; |
404 | if( ! fcs ) return ENOMEM; |
| 383 | * fcs = htonl( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )); |
405 | * fcs = htonl( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )); |
| - | 406 | } |
|
| 384 | return EOK; |
407 | return EOK; |
| 385 | } |
408 | } |
| 386 | 409 | ||
| 387 | int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){ |
410 | int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){ |
| 388 | ERROR_DECLARE; |
411 | ERROR_DECLARE; |
| Line 404... | Line 427... | ||
| 404 | return ENOENT; |
427 | return ENOENT; |
| 405 | } |
428 | } |
| 406 | // proccess packet queue |
429 | // proccess packet queue |
| 407 | next = packet; |
430 | next = packet; |
| 408 | do{ |
431 | do{ |
| 409 | if( ERROR_OCCURRED( eth_prepare_packet( next, ( uint8_t * ) device->addr->value, ethertype ))){ |
432 | if( ERROR_OCCURRED( eth_prepare_packet( device->dummy, next, ( uint8_t * ) device->addr->value, ethertype ))){ |
| 410 | // release invalid packet |
433 | // release invalid packet |
| 411 | tmp = pq_detach( next ); |
434 | tmp = pq_detach( next ); |
| 412 | packet_release( eth_globals.networking_phone, packet_get_id( next )); |
435 | packet_release( eth_globals.networking_phone, packet_get_id( next )); |
| 413 | next = tmp; |
436 | next = tmp; |
| 414 | }else{ |
437 | }else{ |