Changes in uspace/srv/net/nil/eth/eth.c [aadf01e:a000878c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/nil/eth/eth.c
raadf01e ra000878c 70 70 /** Reserved packet prefix length. 71 71 */ 72 #define ETH_PREFIX ( sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t))72 #define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t )) 73 73 74 74 /** Reserved packet suffix length. 75 75 */ 76 #define ETH_SUFFIX sizeof( eth_fcs_t)76 #define ETH_SUFFIX sizeof( eth_fcs_t ) 77 77 78 78 /** Maximum packet content length. … … 86 86 /** Maximum tagged packet content length. 87 87 */ 88 #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 #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 )) 89 89 90 90 /** Minimum tagged packet content length. 91 91 */ 92 #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))92 #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 )) 93 93 94 94 /** Dummy flag shift value. … … 103 103 * Preamble and FCS are mandatory part of the packets. 104 104 */ 105 #define ETH_DUMMY ( 1 << ETH_DUMMY_SHIFT)105 #define ETH_DUMMY ( 1 << ETH_DUMMY_SHIFT ) 106 106 107 107 /** Returns the dummy flag. 108 108 * @see ETH_DUMMY 109 109 */ 110 #define IS_DUMMY( flags) ((flags) Ð_DUMMY)110 #define IS_DUMMY( flags ) (( flags ) & ETH_DUMMY ) 111 111 112 112 /** Device mode flags. … … 115 115 * @see ETH_8023_2_SNAP 116 116 */ 117 #define ETH_MODE_MASK ( 3 << ETH_MODE_SHIFT)117 #define ETH_MODE_MASK ( 3 << ETH_MODE_SHIFT ) 118 118 119 119 /** DIX Ethernet mode flag. 120 120 */ 121 #define ETH_DIX ( 1 << ETH_MODE_SHIFT)121 #define ETH_DIX ( 1 << ETH_MODE_SHIFT ) 122 122 123 123 /** Returns whether the DIX Ethernet mode flag is set. … … 125 125 * @see ETH_DIX 126 126 */ 127 #define IS_DIX( flags) (((flags) Ð_MODE_MASK) == ETH_DIX)127 #define IS_DIX( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_DIX ) 128 128 129 129 /** 802.3 + 802.2 + LSAP mode flag. 130 130 */ 131 #define ETH_8023_2_LSAP ( 2 << ETH_MODE_SHIFT)131 #define ETH_8023_2_LSAP ( 2 << ETH_MODE_SHIFT ) 132 132 133 133 /** Returns whether the 802.3 + 802.2 + LSAP mode flag is set. … … 135 135 * @see ETH_8023_2_LSAP 136 136 */ 137 #define IS_8023_2_LSAP( flags) (((flags) Ð_MODE_MASK) == ETH_8023_2_LSAP)137 #define IS_8023_2_LSAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_LSAP ) 138 138 139 139 /** 802.3 + 802.2 + LSAP + SNAP mode flag. 140 140 */ 141 #define ETH_8023_2_SNAP ( 3 << ETH_MODE_SHIFT)141 #define ETH_8023_2_SNAP ( 3 << ETH_MODE_SHIFT ) 142 142 143 143 /** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. … … 145 145 * @see ETH_8023_2_SNAP 146 146 */ 147 #define IS_8023_2_SNAP( flags) (((flags) Ð_MODE_MASK) == ETH_8023_2_SNAP)147 #define IS_8023_2_SNAP( flags ) ((( flags ) & ETH_MODE_MASK ) == ETH_8023_2_SNAP ) 148 148 149 149 /** Type definition of the ethernet address type. … … 180 180 * @param[in,out] icall The message parameters. 181 181 */ 182 void eth_receiver(ipc_callid_t iid, ipc_call_t * icall);182 void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ); 183 183 184 184 /** Registers new device or updates the MTU of an existing one. … … 194 194 * @returns Other error codes as defined for the netif_get_addr_req() function. 195 195 */ 196 int eth_device_message(device_id_t device_id, services_t service, size_t mtu);196 int eth_device_message( device_id_t device_id, services_t service, size_t mtu ); 197 197 198 198 /** Registers receiving module service. … … 204 204 * @returns ENOMEM if there is not enough memory left. 205 205 */ 206 int eth_register_message(services_t service, int phone);206 int eth_register_message( services_t service, int phone ); 207 207 208 208 /** Returns the device packet dimensions for sending. … … 216 216 * @returns ENOENT if there is no such device. 217 217 */ 218 int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix);218 int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ); 219 219 220 220 /** Returns the device hardware address. … … 226 226 * @returns ENOENT if there no such device. 227 227 */ 228 int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address);228 int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ); 229 229 230 230 /** Sends the packet queue. … … 237 237 * @returns EINVAL if the service parameter is not known. 238 238 */ 239 int eth_send_message(device_id_t device_id, packet_t packet, services_t sender);239 int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ); 240 240 241 241 /*@}*/ … … 251 251 * @returns NULL if the packet address length is not big enough. 252 252 */ 253 eth_proto_ref eth_process_packet(int flags, packet_t packet);253 eth_proto_ref eth_process_packet( int flags, packet_t packet ); 254 254 255 255 /** Prepares the packet for sending. … … 264 264 * @returns ENOMEM if there is not enough memory in the packet. 265 265 */ 266 int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu); 267 268 DEVICE_MAP_IMPLEMENT(eth_devices, eth_device_t) 269 270 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t) 271 272 int nil_device_state_msg(int nil_phone, device_id_t device_id, int state){ 273 int index; 274 eth_proto_ref proto; 275 276 fibril_rwlock_read_lock(ð_globals.protos_lock); 277 for(index = eth_protos_count(ð_globals.protos) - 1; index >= 0; -- index){ 278 proto = eth_protos_get_index(ð_globals.protos, index); 279 if(proto && proto->phone){ 280 il_device_state_msg(proto->phone, device_id, state, proto->service); 281 } 282 } 283 fibril_rwlock_read_unlock(ð_globals.protos_lock); 266 int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu ); 267 268 DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) 269 270 INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) 271 272 int nil_device_state_msg( int nil_phone, device_id_t device_id, int state ){ 273 int index; 274 eth_proto_ref proto; 275 276 fibril_rwlock_read_lock( & eth_globals.protos_lock ); 277 for( index = eth_protos_count( & eth_globals.protos ) - 1; index >= 0; -- index ){ 278 proto = eth_protos_get_index( & eth_globals.protos, index ); 279 if( proto && proto->phone ) il_device_state_msg( proto->phone, device_id, state, proto->service ); 280 } 281 fibril_rwlock_read_unlock( & eth_globals.protos_lock ); 284 282 return EOK; 285 283 } 286 284 287 int nil_initialize( int net_phone){285 int nil_initialize( int net_phone ){ 288 286 ERROR_DECLARE; 289 287 290 fibril_rwlock_initialize( ð_globals.devices_lock);291 fibril_rwlock_initialize( ð_globals.protos_lock);292 fibril_rwlock_write_lock( ð_globals.devices_lock);293 fibril_rwlock_write_lock( ð_globals.protos_lock);288 fibril_rwlock_initialize( & eth_globals.devices_lock ); 289 fibril_rwlock_initialize( & eth_globals.protos_lock ); 290 fibril_rwlock_write_lock( & eth_globals.devices_lock ); 291 fibril_rwlock_write_lock( & eth_globals.protos_lock ); 294 292 eth_globals.net_phone = net_phone; 295 eth_globals.broadcast_addr = measured_string_create_bulk("\xFF\xFF\xFF\xFF\xFF\xFF", CONVERT_SIZE(uint8_t, char, ETH_ADDR)); 296 if(! eth_globals.broadcast_addr){ 297 return ENOMEM; 298 } 299 ERROR_PROPAGATE(eth_devices_initialize(ð_globals.devices)); 300 if(ERROR_OCCURRED(eth_protos_initialize(ð_globals.protos))){ 301 eth_devices_destroy(ð_globals.devices); 293 eth_globals.broadcast_addr = measured_string_create_bulk( "\xFF\xFF\xFF\xFF\xFF\xFF", CONVERT_SIZE( uint8_t, char, ETH_ADDR )); 294 if( ! eth_globals.broadcast_addr ) return ENOMEM; 295 ERROR_PROPAGATE( eth_devices_initialize( & eth_globals.devices )); 296 if( ERROR_OCCURRED( eth_protos_initialize( & eth_globals.protos ))){ 297 eth_devices_destroy( & eth_globals.devices ); 302 298 return ERROR_CODE; 303 299 } 304 fibril_rwlock_write_unlock( ð_globals.protos_lock);305 fibril_rwlock_write_unlock( ð_globals.devices_lock);300 fibril_rwlock_write_unlock( & eth_globals.protos_lock ); 301 fibril_rwlock_write_unlock( & eth_globals.devices_lock ); 306 302 return EOK; 307 303 } 308 304 309 int eth_device_message( device_id_t device_id, services_t service, size_t mtu){305 int eth_device_message( device_id_t device_id, services_t service, size_t mtu ){ 310 306 ERROR_DECLARE; 311 307 312 eth_device_ref 313 int 314 measured_string_t names[2] = {{str_dup("ETH_MODE"), 8}, {str_dup("ETH_DUMMY"), 9}};315 measured_string_ref 316 size_t count = sizeof(names) / sizeof(measured_string_t);317 char * 318 eth_proto_ref 319 320 fibril_rwlock_write_lock( ð_globals.devices_lock);308 eth_device_ref device; 309 int index; 310 measured_string_t names[ 2 ] = {{ str_dup("ETH_MODE"), 8 }, { str_dup("ETH_DUMMY"), 9 }}; 311 measured_string_ref configuration; 312 size_t count = sizeof( names ) / sizeof( measured_string_t ); 313 char * data; 314 eth_proto_ref proto; 315 316 fibril_rwlock_write_lock( & eth_globals.devices_lock ); 321 317 // an existing device? 322 device = eth_devices_find( ð_globals.devices, device_id);323 if( device){324 if( device->service != service){325 printf( "Device %d already exists\n", device->device_id);326 fibril_rwlock_write_unlock( ð_globals.devices_lock);318 device = eth_devices_find( & eth_globals.devices, device_id ); 319 if( device ){ 320 if( device->service != service ){ 321 printf( "Device %d already exists\n", device->device_id ); 322 fibril_rwlock_write_unlock( & eth_globals.devices_lock ); 327 323 return EEXIST; 328 324 }else{ 329 325 // update mtu 330 if(( mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))){326 if(( mtu > 0 ) && ( mtu <= ETH_MAX_TAGGED_CONTENT( device->flags ))){ 331 327 device->mtu = mtu; 332 328 }else{ 333 device->mtu = ETH_MAX_TAGGED_CONTENT( device->flags);329 device->mtu = ETH_MAX_TAGGED_CONTENT( device->flags ); 334 330 } 335 printf( "Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu);336 fibril_rwlock_write_unlock( ð_globals.devices_lock);331 printf( "Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu ); 332 fibril_rwlock_write_unlock( & eth_globals.devices_lock ); 337 333 // notify all upper layer modules 338 fibril_rwlock_read_lock( ð_globals.protos_lock);339 for( index = 0; index < eth_protos_count(ð_globals.protos); ++ index){340 proto = eth_protos_get_index( ð_globals.protos, index);341 if ( proto->phone){342 il_mtu_changed_msg( proto->phone, device->device_id, device->mtu, proto->service);334 fibril_rwlock_read_lock( & eth_globals.protos_lock ); 335 for( index = 0; index < eth_protos_count( & eth_globals.protos ); ++ index ){ 336 proto = eth_protos_get_index( & eth_globals.protos, index ); 337 if ( proto->phone ){ 338 il_mtu_changed_msg( proto->phone, device->device_id, device->mtu, proto->service ); 343 339 } 344 340 } 345 fibril_rwlock_read_unlock( ð_globals.protos_lock);341 fibril_rwlock_read_unlock( & eth_globals.protos_lock ); 346 342 return EOK; 347 343 } 348 344 }else{ 349 345 // create a new device 350 device = (eth_device_ref) malloc(sizeof(eth_device_t)); 351 if(! device){ 352 return ENOMEM; 353 } 346 device = ( eth_device_ref ) malloc( sizeof( eth_device_t )); 347 if( ! device ) return ENOMEM; 354 348 device->device_id = device_id; 355 349 device->service = service; 356 350 device->flags = 0; 357 if(( mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))){351 if(( mtu > 0 ) && ( mtu <= ETH_MAX_TAGGED_CONTENT( device->flags ))){ 358 352 device->mtu = mtu; 359 353 }else{ 360 device->mtu = ETH_MAX_TAGGED_CONTENT( device->flags);361 } 362 configuration = & names[0];363 if( ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone, device->device_id, &configuration, count, &data))){364 fibril_rwlock_write_unlock( ð_globals.devices_lock);365 free( device);354 device->mtu = ETH_MAX_TAGGED_CONTENT( device->flags ); 355 } 356 configuration = & names[ 0 ]; 357 if( ERROR_OCCURRED( net_get_device_conf_req( eth_globals.net_phone, device->device_id, & configuration, count, & data ))){ 358 fibril_rwlock_write_unlock( & eth_globals.devices_lock ); 359 free( device ); 366 360 return ERROR_CODE; 367 361 } 368 if( configuration){369 if( ! str_lcmp(configuration[0].value, "DIX", configuration[0].length)){362 if( configuration ){ 363 if( ! str_lcmp( configuration[ 0 ].value, "DIX", configuration[ 0 ].length )){ 370 364 device->flags |= ETH_DIX; 371 }else if( ! str_lcmp(configuration[0].value, "8023_2_LSAP", configuration[0].length)){365 }else if( ! str_lcmp( configuration[ 0 ].value, "8023_2_LSAP", configuration[ 0 ].length )){ 372 366 device->flags |= ETH_8023_2_LSAP; 373 367 }else device->flags |= ETH_8023_2_SNAP; 374 if(( configuration[1].value) && (configuration[1].value[0] == 'y')){368 if(( configuration[ 1 ].value ) && ( configuration[ 1 ].value[ 0 ] == 'y' )){ 375 369 device->flags |= ETH_DUMMY; 376 370 } 377 net_free_settings( configuration, data);371 net_free_settings( configuration, data ); 378 372 }else{ 379 373 device->flags |= ETH_8023_2_SNAP; 380 374 } 381 375 // bind the device driver 382 device->phone = netif_bind_service( device->service, device->device_id, SERVICE_ETHERNET, eth_receiver);383 if( device->phone < 0){384 fibril_rwlock_write_unlock( ð_globals.devices_lock);385 free( device);376 device->phone = netif_bind_service( device->service, device->device_id, SERVICE_ETHERNET, eth_receiver ); 377 if( device->phone < 0 ){ 378 fibril_rwlock_write_unlock( & eth_globals.devices_lock ); 379 free( device ); 386 380 return device->phone; 387 381 } 388 382 // get hardware address 389 if( ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, &device->addr, &device->addr_data))){390 fibril_rwlock_write_unlock( ð_globals.devices_lock);391 free( device);383 if( ERROR_OCCURRED( netif_get_addr_req( device->phone, device->device_id, & device->addr, & device->addr_data ))){ 384 fibril_rwlock_write_unlock( & eth_globals.devices_lock ); 385 free( device ); 392 386 return ERROR_CODE; 393 387 } 394 388 // add to the cache 395 index = eth_devices_add( ð_globals.devices, device->device_id, device);396 if( index < 0){397 fibril_rwlock_write_unlock( ð_globals.devices_lock);398 free( device->addr);399 free( device->addr_data);400 free( device);389 index = eth_devices_add( & eth_globals.devices, device->device_id, device ); 390 if( index < 0 ){ 391 fibril_rwlock_write_unlock( & eth_globals.devices_lock ); 392 free( device->addr ); 393 free( device->addr_data ); 394 free( device ); 401 395 return index; 402 396 } 403 printf( "New device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n\taddress\t= %X:%X:%X:%X:%X:%X\n\tflags\t= 0x%x\n", device->device_id, device->service, device->mtu, device->addr_data[0], device->addr_data[1], device->addr_data[2], device->addr_data[3], device->addr_data[4], device->addr_data[5], device->flags);404 } 405 fibril_rwlock_write_unlock( ð_globals.devices_lock);397 printf( "New device registered:\n\tid\t= %d\n\tservice\t= %d\n\tMTU\t= %d\n\taddress\t= %X:%X:%X:%X:%X:%X\n\tflags\t= 0x%x\n", device->device_id, device->service, device->mtu, device->addr_data[ 0 ], device->addr_data[ 1 ], device->addr_data[ 2 ], device->addr_data[ 3 ], device->addr_data[ 4 ], device->addr_data[ 5 ], device->flags ); 398 } 399 fibril_rwlock_write_unlock( & eth_globals.devices_lock ); 406 400 return EOK; 407 401 } 408 402 409 eth_proto_ref eth_process_packet( int flags, packet_t packet){403 eth_proto_ref eth_process_packet( int flags, packet_t packet ){ 410 404 ERROR_DECLARE; 411 405 412 eth_header_snap_ref 413 size_t 414 eth_type_t 415 size_t 416 size_t 417 eth_fcs_ref 418 uint8_t * 419 420 length = packet_get_data_length( packet);421 if( IS_DUMMY(flags)){422 packet_trim( packet, sizeof(eth_preamble_t), 0);423 } 424 if( length < sizeof(eth_header_t) + ETH_MIN_CONTENT + (IS_DUMMY(flags) ? ETH_SUFFIX : 0)) return NULL;425 data = packet_get_data( packet);426 header = ( eth_header_snap_ref) data;427 type = ntohs( header->header.ethertype);428 if( type >= ETH_MIN_PROTO){406 eth_header_snap_ref header; 407 size_t length; 408 eth_type_t type; 409 size_t prefix; 410 size_t suffix; 411 eth_fcs_ref fcs; 412 uint8_t * data; 413 414 length = packet_get_data_length( packet ); 415 if( IS_DUMMY( flags )){ 416 packet_trim( packet, sizeof( eth_preamble_t ), 0 ); 417 } 418 if( length < sizeof( eth_header_t ) + ETH_MIN_CONTENT + ( IS_DUMMY( flags ) ? ETH_SUFFIX : 0 )) return NULL; 419 data = packet_get_data( packet ); 420 header = ( eth_header_snap_ref ) data; 421 type = ntohs( header->header.ethertype ); 422 if( type >= ETH_MIN_PROTO ){ 429 423 // DIX Ethernet 430 prefix = sizeof( eth_header_t);424 prefix = sizeof( eth_header_t ); 431 425 suffix = 0; 432 fcs = ( eth_fcs_ref) data + length - sizeof(eth_fcs_t);433 length -= sizeof( eth_fcs_t);434 }else if( type <= ETH_MAX_CONTENT){426 fcs = ( eth_fcs_ref ) data + length - sizeof( eth_fcs_t ); 427 length -= sizeof( eth_fcs_t ); 428 }else if( type <= ETH_MAX_CONTENT ){ 435 429 // translate "LSAP" values 436 if(( header->lsap.dsap == ETH_LSAP_GLSAP) && (header->lsap.ssap == ETH_LSAP_GLSAP)){430 if(( header->lsap.dsap == ETH_LSAP_GLSAP ) && ( header->lsap.ssap == ETH_LSAP_GLSAP )){ 437 431 // raw packet 438 432 // discard 439 433 return NULL; 440 }else if(( header->lsap.dsap == ETH_LSAP_SNAP) && (header->lsap.ssap == ETH_LSAP_SNAP)){434 }else if(( header->lsap.dsap == ETH_LSAP_SNAP ) && ( header->lsap.ssap == ETH_LSAP_SNAP )){ 441 435 // IEEE 802.3 + 802.2 + LSAP + SNAP 442 436 // organization code not supported 443 type = ntohs( header->snap.ethertype);444 prefix = sizeof( eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t);437 type = ntohs( header->snap.ethertype ); 438 prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t ); 445 439 }else{ 446 440 // IEEE 802.3 + 802.2 LSAP 447 type = lsap_map( header->lsap.dsap);448 prefix = sizeof( eth_header_t) + sizeof(eth_header_lsap_t);449 } 450 suffix = ( type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0u;451 fcs = ( eth_fcs_ref) data + prefix + type + suffix;441 type = lsap_map( header->lsap.dsap ); 442 prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t); 443 } 444 suffix = ( type < ETH_MIN_CONTENT ) ? ETH_MIN_CONTENT - type : 0u; 445 fcs = ( eth_fcs_ref ) data + prefix + type + suffix; 452 446 suffix += length - prefix - type; 453 447 length = prefix + type + suffix; … … 456 450 return NULL; 457 451 } 458 if( IS_DUMMY(flags)){459 if(( ~ compute_crc32(~ 0u, data, length * 8)) != ntohl(*fcs)){452 if( IS_DUMMY( flags )){ 453 if(( ~ compute_crc32( ~ 0u, data, length * 8 )) != ntohl( * fcs )){ 460 454 return NULL; 461 455 } 462 suffix += sizeof( eth_fcs_t);463 } 464 if( ERROR_OCCURRED(packet_set_addr(packet, header->header.source_address, header->header.destination_address, ETH_ADDR))465 || ERROR_OCCURRED(packet_trim(packet, prefix, suffix))){456 suffix += sizeof( eth_fcs_t ); 457 } 458 if( ERROR_OCCURRED( packet_set_addr( packet, header->header.source_address, header->header.destination_address, ETH_ADDR )) 459 || ERROR_OCCURRED( packet_trim( packet, prefix, suffix ))){ 466 460 return NULL; 467 461 } 468 return eth_protos_find( ð_globals.protos, type);469 } 470 471 int nil_received_msg( int nil_phone, device_id_t device_id, packet_t packet, services_t target){472 eth_proto_ref 473 packet_t 474 eth_device_ref 475 int 476 477 fibril_rwlock_read_lock( ð_globals.devices_lock);478 device = eth_devices_find( ð_globals.devices, device_id);479 if( ! device){480 fibril_rwlock_read_unlock( ð_globals.devices_lock);462 return eth_protos_find( & eth_globals.protos, type ); 463 } 464 465 int nil_received_msg( int nil_phone, device_id_t device_id, packet_t packet, services_t target ){ 466 eth_proto_ref proto; 467 packet_t next; 468 eth_device_ref device; 469 int flags; 470 471 fibril_rwlock_read_lock( & eth_globals.devices_lock ); 472 device = eth_devices_find( & eth_globals.devices, device_id ); 473 if( ! device ){ 474 fibril_rwlock_read_unlock( & eth_globals.devices_lock ); 481 475 return ENOENT; 482 476 } 483 477 flags = device->flags; 484 fibril_rwlock_read_unlock( ð_globals.devices_lock);485 fibril_rwlock_read_lock( ð_globals.protos_lock);478 fibril_rwlock_read_unlock( & eth_globals.devices_lock ); 479 fibril_rwlock_read_lock( & eth_globals.protos_lock ); 486 480 do{ 487 next = pq_detach( packet);488 proto = eth_process_packet( flags, packet);489 if( proto){490 il_received_msg( proto->phone, device_id, packet, proto->service);481 next = pq_detach( packet ); 482 proto = eth_process_packet( flags, packet ); 483 if( proto ){ 484 il_received_msg( proto->phone, device_id, packet, proto->service ); 491 485 }else{ 492 486 // drop invalid/unknown 493 pq_release( eth_globals.net_phone, packet_get_id(packet));487 pq_release( eth_globals.net_phone, packet_get_id( packet )); 494 488 } 495 489 packet = next; 496 }while( packet);497 fibril_rwlock_read_unlock( ð_globals.protos_lock);490 }while( packet ); 491 fibril_rwlock_read_unlock( & eth_globals.protos_lock ); 498 492 return EOK; 499 493 } 500 494 501 int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){ 502 eth_device_ref device; 503 504 if(!(addr_len && prefix && content && suffix)){ 505 return EBADMEM; 506 } 507 fibril_rwlock_read_lock(ð_globals.devices_lock); 508 device = eth_devices_find(ð_globals.devices, device_id); 509 if(! device){ 510 fibril_rwlock_read_unlock(ð_globals.devices_lock); 495 int eth_packet_space_message( device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix ){ 496 eth_device_ref device; 497 498 if( !( addr_len && prefix && content && suffix )) return EBADMEM; 499 fibril_rwlock_read_lock( & eth_globals.devices_lock ); 500 device = eth_devices_find( & eth_globals.devices, device_id ); 501 if( ! device ){ 502 fibril_rwlock_read_unlock( & eth_globals.devices_lock ); 511 503 return ENOENT; 512 504 } 513 * content = device->mtu;514 fibril_rwlock_read_unlock( ð_globals.devices_lock);515 * addr_len = ETH_ADDR;516 * prefix = ETH_PREFIX;517 * suffix = ETH_MIN_CONTENT + ETH_SUFFIX;505 * content = device->mtu; 506 fibril_rwlock_read_unlock( & eth_globals.devices_lock ); 507 * addr_len = ETH_ADDR; 508 * prefix = ETH_PREFIX; 509 * suffix = ETH_MIN_CONTENT + ETH_SUFFIX; 518 510 return EOK; 519 511 } 520 512 521 int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address){ 522 eth_device_ref device; 523 524 if(! address){ 525 return EBADMEM; 526 } 527 if(type == ETH_BROADCAST_ADDR){ 528 *address = eth_globals.broadcast_addr; 513 int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address ){ 514 eth_device_ref device; 515 516 if( ! address ) return EBADMEM; 517 if( type == ETH_BROADCAST_ADDR ){ 518 * address = eth_globals.broadcast_addr; 529 519 }else{ 530 fibril_rwlock_read_lock( ð_globals.devices_lock);531 device = eth_devices_find( ð_globals.devices, device_id);532 if( ! device){533 fibril_rwlock_read_unlock( ð_globals.devices_lock);520 fibril_rwlock_read_lock( & eth_globals.devices_lock ); 521 device = eth_devices_find( & eth_globals.devices, device_id ); 522 if( ! device ){ 523 fibril_rwlock_read_unlock( & eth_globals.devices_lock ); 534 524 return ENOENT; 535 525 } 536 *address = device->addr; 537 fibril_rwlock_read_unlock(ð_globals.devices_lock); 538 } 539 return (*address) ? EOK : ENOENT; 540 } 541 542 int eth_register_message(services_t service, int phone){ 543 eth_proto_ref proto; 544 int protocol; 545 int index; 546 547 protocol = protocol_map(SERVICE_ETHERNET, service); 548 if(! protocol){ 549 return ENOENT; 550 } 551 fibril_rwlock_write_lock(ð_globals.protos_lock); 552 proto = eth_protos_find(ð_globals.protos, protocol); 553 if(proto){ 526 * address = device->addr; 527 fibril_rwlock_read_unlock( & eth_globals.devices_lock ); 528 } 529 return ( * address ) ? EOK : ENOENT; 530 } 531 532 int eth_register_message( services_t service, int phone ){ 533 eth_proto_ref proto; 534 int protocol; 535 int index; 536 537 protocol = protocol_map( SERVICE_ETHERNET, service ); 538 if( ! protocol ) return ENOENT; 539 fibril_rwlock_write_lock( & eth_globals.protos_lock ); 540 proto = eth_protos_find( & eth_globals.protos, protocol ); 541 if( proto ){ 554 542 proto->phone = phone; 555 fibril_rwlock_write_unlock( ð_globals.protos_lock);543 fibril_rwlock_write_unlock( & eth_globals.protos_lock ); 556 544 return EOK; 557 545 }else{ 558 proto = ( eth_proto_ref) malloc(sizeof(eth_proto_t));559 if( ! proto){560 fibril_rwlock_write_unlock( ð_globals.protos_lock);546 proto = ( eth_proto_ref ) malloc( sizeof( eth_proto_t )); 547 if( ! proto ){ 548 fibril_rwlock_write_unlock( & eth_globals.protos_lock ); 561 549 return ENOMEM; 562 550 } … … 564 552 proto->protocol = protocol; 565 553 proto->phone = phone; 566 index = eth_protos_add( ð_globals.protos, protocol, proto);567 if( index < 0){568 fibril_rwlock_write_unlock( ð_globals.protos_lock);569 free( proto);554 index = eth_protos_add( & eth_globals.protos, protocol, proto ); 555 if( index < 0 ){ 556 fibril_rwlock_write_unlock( & eth_globals.protos_lock ); 557 free( proto ); 570 558 return index; 571 559 } 572 560 } 573 printf( "New protocol registered:\n\tprotocol\t= 0x%x\n\tservice\t= %d\n\tphone\t= %d\n", proto->protocol, proto->service, proto->phone);574 fibril_rwlock_write_unlock( ð_globals.protos_lock);561 printf( "New protocol registered:\n\tprotocol\t= 0x%x\n\tservice\t= %d\n\tphone\t= %d\n", proto->protocol, proto->service, proto->phone ); 562 fibril_rwlock_write_unlock( & eth_globals.protos_lock ); 575 563 return EOK; 576 564 } 577 565 578 int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu){ 579 eth_header_snap_ref header; 580 eth_header_lsap_ref header_lsap; 581 eth_header_ref header_dix; 582 eth_fcs_ref fcs; 583 uint8_t * src; 584 uint8_t * dest; 585 size_t length; 586 int i; 587 void * padding; 588 eth_preamble_ref preamble; 589 590 i = packet_get_addr(packet, &src, &dest); 591 if(i < 0){ 592 return i; 593 } 594 if(i != ETH_ADDR){ 595 return EINVAL; 596 } 597 length = packet_get_data_length(packet); 598 if(length > mtu){ 599 return EINVAL; 600 } 601 if(length < ETH_MIN_TAGGED_CONTENT(flags)){ 602 padding = packet_suffix(packet, ETH_MIN_TAGGED_CONTENT(flags) - length); 603 if(! padding){ 604 return ENOMEM; 605 } 606 bzero(padding, ETH_MIN_TAGGED_CONTENT(flags) - length); 607 } 608 if(IS_DIX(flags)){ 609 header_dix = PACKET_PREFIX(packet, eth_header_t); 610 if(! header_dix){ 611 return ENOMEM; 612 } 613 header_dix->ethertype = (uint16_t) ethertype; 614 memcpy(header_dix->source_address, src_addr, ETH_ADDR); 615 memcpy(header_dix->destination_address, dest, ETH_ADDR); 616 src = &header_dix->destination_address[0]; 617 }else if(IS_8023_2_LSAP(flags)){ 618 header_lsap = PACKET_PREFIX(packet, eth_header_lsap_t); 619 if(! header_lsap){ 620 return ENOMEM; 621 } 622 header_lsap->header.ethertype = htons(length + sizeof(eth_header_lsap_t)); 623 header_lsap->lsap.dsap = lsap_unmap(ntohs(ethertype)); 566 int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu ){ 567 eth_header_snap_ref header; 568 eth_header_lsap_ref header_lsap; 569 eth_header_ref header_dix; 570 eth_fcs_ref fcs; 571 uint8_t * src; 572 uint8_t * dest; 573 size_t length; 574 int i; 575 void * padding; 576 eth_preamble_ref preamble; 577 578 i = packet_get_addr( packet, & src, & dest ); 579 if( i < 0 ) return i; 580 if( i != ETH_ADDR ) return EINVAL; 581 length = packet_get_data_length( packet ); 582 if( length > mtu ) return EINVAL; 583 if( length < ETH_MIN_TAGGED_CONTENT( flags )){ 584 padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length ); 585 if( ! padding ) return ENOMEM; 586 bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length ); 587 } 588 if( IS_DIX( flags )){ 589 header_dix = PACKET_PREFIX( packet, eth_header_t ); 590 if( ! header_dix ) return ENOMEM; 591 header_dix->ethertype = ( uint16_t ) ethertype; 592 memcpy( header_dix->source_address, src_addr, ETH_ADDR ); 593 memcpy( header_dix->destination_address, dest, ETH_ADDR ); 594 src = & header_dix->destination_address[ 0 ]; 595 }else if( IS_8023_2_LSAP( flags )){ 596 header_lsap = PACKET_PREFIX( packet, eth_header_lsap_t ); 597 if( ! header_lsap ) return ENOMEM; 598 header_lsap->header.ethertype = htons( length + sizeof( eth_header_lsap_t )); 599 header_lsap->lsap.dsap = lsap_unmap( ntohs( ethertype )); 624 600 header_lsap->lsap.ssap = header_lsap->lsap.dsap; 625 601 header_lsap->lsap.ctrl = IEEE_8023_2_UI; 626 memcpy(header_lsap->header.source_address, src_addr, ETH_ADDR); 627 memcpy(header_lsap->header.destination_address, dest, ETH_ADDR); 628 src = &header_lsap->header.destination_address[0]; 629 }else if(IS_8023_2_SNAP(flags)){ 630 header = PACKET_PREFIX(packet, eth_header_snap_t); 631 if(! header){ 632 return ENOMEM; 633 } 634 header->header.ethertype = htons(length + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t)); 635 header->lsap.dsap = (uint16_t) ETH_LSAP_SNAP; 602 memcpy( header_lsap->header.source_address, src_addr, ETH_ADDR ); 603 memcpy( header_lsap->header.destination_address, dest, ETH_ADDR ); 604 src = & header_lsap->header.destination_address[ 0 ]; 605 }else if( IS_8023_2_SNAP( flags )){ 606 header = PACKET_PREFIX( packet, eth_header_snap_t ); 607 if( ! header ) return ENOMEM; 608 header->header.ethertype = htons( length + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t )); 609 header->lsap.dsap = ( uint16_t ) ETH_LSAP_SNAP; 636 610 header->lsap.ssap = header->lsap.dsap; 637 611 header->lsap.ctrl = IEEE_8023_2_UI; 638 for(i = 0; i < 3; ++ i){ 639 header->snap.protocol[i] = 0; 640 } 641 header->snap.ethertype = (uint16_t) ethertype; 642 memcpy(header->header.source_address, src_addr, ETH_ADDR); 643 memcpy(header->header.destination_address, dest, ETH_ADDR); 644 src = &header->header.destination_address[0]; 645 } 646 if(IS_DUMMY(flags)){ 647 preamble = PACKET_PREFIX(packet, eth_preamble_t); 648 if(! preamble){ 649 return ENOMEM; 650 } 651 for(i = 0; i < 7; ++ i){ 652 preamble->preamble[i] = ETH_PREAMBLE; 653 } 612 for( i = 0; i < 3; ++ i ) header->snap.protocol[ i ] = 0; 613 header->snap.ethertype = ( uint16_t ) ethertype; 614 memcpy( header->header.source_address, src_addr, ETH_ADDR ); 615 memcpy( header->header.destination_address, dest, ETH_ADDR ); 616 src = & header->header.destination_address[ 0 ]; 617 } 618 if( IS_DUMMY( flags )){ 619 preamble = PACKET_PREFIX( packet, eth_preamble_t ); 620 if( ! preamble ) return ENOMEM; 621 for( i = 0; i < 7; ++ i ) preamble->preamble[ i ] = ETH_PREAMBLE; 654 622 preamble->sfd = ETH_SFD; 655 fcs = PACKET_SUFFIX(packet, eth_fcs_t); 656 if(! fcs){ 657 return ENOMEM; 658 } 659 *fcs = htonl(~ compute_crc32(~ 0u, src, length * 8)); 623 fcs = PACKET_SUFFIX( packet, eth_fcs_t ); 624 if( ! fcs ) return ENOMEM; 625 * fcs = htonl( ~ compute_crc32( ~ 0u, src, length * 8 )); 660 626 } 661 627 return EOK; 662 628 } 663 629 664 int eth_send_message( device_id_t device_id, packet_t packet, services_t sender){630 int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){ 665 631 ERROR_DECLARE; 666 632 667 eth_device_ref 668 packet_t 669 packet_t 670 int 671 672 ethertype = htons( protocol_map(SERVICE_ETHERNET, sender));673 if( ! ethertype){674 pq_release( eth_globals.net_phone, packet_get_id(packet));633 eth_device_ref device; 634 packet_t next; 635 packet_t tmp; 636 int ethertype; 637 638 ethertype = htons( protocol_map( SERVICE_ETHERNET, sender )); 639 if( ! ethertype ){ 640 pq_release( eth_globals.net_phone, packet_get_id( packet )); 675 641 return EINVAL; 676 642 } 677 fibril_rwlock_read_lock( ð_globals.devices_lock);678 device = eth_devices_find( ð_globals.devices, device_id);679 if( ! device){680 fibril_rwlock_read_unlock( ð_globals.devices_lock);643 fibril_rwlock_read_lock( & eth_globals.devices_lock ); 644 device = eth_devices_find( & eth_globals.devices, device_id ); 645 if( ! device ){ 646 fibril_rwlock_read_unlock( & eth_globals.devices_lock ); 681 647 return ENOENT; 682 648 } … … 684 650 next = packet; 685 651 do{ 686 if( ERROR_OCCURRED(eth_prepare_packet(device->flags, next, (uint8_t *) device->addr->value, ethertype, device->mtu))){652 if( ERROR_OCCURRED( eth_prepare_packet( device->flags, next, ( uint8_t * ) device->addr->value, ethertype, device->mtu ))){ 687 653 // release invalid packet 688 tmp = pq_detach(next); 689 if(next == packet){ 690 packet = tmp; 691 } 692 pq_release(eth_globals.net_phone, packet_get_id(next)); 654 tmp = pq_detach( next ); 655 if( next == packet ) packet = tmp; 656 pq_release( eth_globals.net_phone, packet_get_id( next )); 693 657 next = tmp; 694 658 }else{ 695 next = pq_next( next);696 } 697 }while( next);659 next = pq_next( next ); 660 } 661 }while( next ); 698 662 // send packet queue 699 if( packet){700 netif_send_msg( device->phone, device_id, packet, SERVICE_ETHERNET);701 } 702 fibril_rwlock_read_unlock( ð_globals.devices_lock);663 if( packet ){ 664 netif_send_msg( device->phone, device_id, packet, SERVICE_ETHERNET ); 665 } 666 fibril_rwlock_read_unlock( & eth_globals.devices_lock ); 703 667 return EOK; 704 668 } 705 669 706 int nil_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){670 int nil_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ 707 671 ERROR_DECLARE; 708 672 709 measured_string_ref 710 packet_t 711 712 // printf( "message %d - %d\n", IPC_GET_METHOD(*call), NET_NIL_FIRST);713 * answer_count = 0;714 switch( IPC_GET_METHOD(*call)){673 measured_string_ref address; 674 packet_t packet; 675 676 // printf( "message %d - %d\n", IPC_GET_METHOD( * call ), NET_NIL_FIRST ); 677 * answer_count = 0; 678 switch( IPC_GET_METHOD( * call )){ 715 679 case IPC_M_PHONE_HUNGUP: 716 680 return EOK; 717 681 case NET_NIL_DEVICE: 718 return eth_device_message( IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), IPC_GET_MTU(call));682 return eth_device_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), IPC_GET_MTU( call )); 719 683 case NET_NIL_SEND: 720 ERROR_PROPAGATE( packet_translate(eth_globals.net_phone, &packet, IPC_GET_PACKET(call)));721 return eth_send_message( IPC_GET_DEVICE(call), packet, IPC_GET_SERVICE(call));684 ERROR_PROPAGATE( packet_translate( eth_globals.net_phone, & packet, IPC_GET_PACKET( call ))); 685 return eth_send_message( IPC_GET_DEVICE( call ), packet, IPC_GET_SERVICE( call )); 722 686 case NET_NIL_PACKET_SPACE: 723 ERROR_PROPAGATE( eth_packet_space_message(IPC_GET_DEVICE(call), IPC_SET_ADDR(answer), IPC_SET_PREFIX(answer), IPC_SET_CONTENT(answer), IPC_SET_SUFFIX(answer)));724 * answer_count = 4;687 ERROR_PROPAGATE( eth_packet_space_message( IPC_GET_DEVICE( call ), IPC_SET_ADDR( answer ), IPC_SET_PREFIX( answer ), IPC_SET_CONTENT( answer ), IPC_SET_SUFFIX( answer ))); 688 * answer_count = 4; 725 689 return EOK; 726 690 case NET_NIL_ADDR: 727 ERROR_PROPAGATE( eth_addr_message(IPC_GET_DEVICE(call), ETH_LOCAL_ADDR, &address));728 return measured_strings_reply( address, 1);691 ERROR_PROPAGATE( eth_addr_message( IPC_GET_DEVICE( call ), ETH_LOCAL_ADDR, & address )); 692 return measured_strings_reply( address, 1 ); 729 693 case NET_NIL_BROADCAST_ADDR: 730 ERROR_PROPAGATE( eth_addr_message(IPC_GET_DEVICE(call), ETH_BROADCAST_ADDR, &address));731 return measured_strings_reply( address, 1);694 ERROR_PROPAGATE( eth_addr_message( IPC_GET_DEVICE( call ), ETH_BROADCAST_ADDR, & address )); 695 return measured_strings_reply( address, 1 ); 732 696 case IPC_M_CONNECT_TO_ME: 733 return eth_register_message( NIL_GET_PROTO(call), IPC_GET_PHONE(call));697 return eth_register_message( NIL_GET_PROTO( call ), IPC_GET_PHONE( call )); 734 698 } 735 699 return ENOTSUP; 736 700 } 737 701 738 void eth_receiver( ipc_callid_t iid, ipc_call_t * icall){702 void eth_receiver( ipc_callid_t iid, ipc_call_t * icall ){ 739 703 ERROR_DECLARE; 740 704 741 packet_t 742 743 while( true){744 // printf( "message %d - %d\n", IPC_GET_METHOD(*icall), NET_NIL_FIRST);745 switch( IPC_GET_METHOD(*icall)){705 packet_t packet; 706 707 while( true ){ 708 // printf( "message %d - %d\n", IPC_GET_METHOD( * icall ), NET_NIL_FIRST ); 709 switch( IPC_GET_METHOD( * icall )){ 746 710 case NET_NIL_DEVICE_STATE: 747 nil_device_state_msg( 0, IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));748 ipc_answer_0( iid, EOK);711 nil_device_state_msg( 0, IPC_GET_DEVICE( icall ), IPC_GET_STATE( icall )); 712 ipc_answer_0( iid, EOK ); 749 713 break; 750 714 case NET_NIL_RECEIVED: 751 if( ! ERROR_OCCURRED(packet_translate(eth_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){752 ERROR_CODE = nil_received_msg( 0, IPC_GET_DEVICE(icall), packet, 0);715 if( ! ERROR_OCCURRED( packet_translate( eth_globals.net_phone, & packet, IPC_GET_PACKET( icall )))){ 716 ERROR_CODE = nil_received_msg( 0, IPC_GET_DEVICE( icall ), packet, 0 ); 753 717 } 754 ipc_answer_0( iid, (ipcarg_t) ERROR_CODE);718 ipc_answer_0( iid, ( ipcarg_t ) ERROR_CODE ); 755 719 break; 756 720 default: 757 ipc_answer_0( iid, (ipcarg_t) ENOTSUP);758 } 759 iid = async_get_call( icall);721 ipc_answer_0( iid, ( ipcarg_t ) ENOTSUP ); 722 } 723 iid = async_get_call( icall ); 760 724 } 761 725 }
Note:
See TracChangeset
for help on using the changeset viewer.