Rev 4077 | Rev 4192 | 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{ |