Changeset 858fc90 in mainline for uspace/srv/net/il/arp/arp.c
- Timestamp:
- 2010-03-15T19:35:25Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6092b56e
- Parents:
- 92307f1 (diff), 4684368 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/arp/arp.c
r92307f1 r858fc90 73 73 arp_globals_t arp_globals; 74 74 75 /** Clears the device specific data. 76 * @param[in] device The device specific data. 77 */ 78 void arp_clear_device(arp_device_ref device); 79 75 80 /** Creates new protocol specific data. 76 81 * Allocates and returns the needed memory block as the proto parameter. … … 81 86 * @returns ENOMEM if there is not enough memory left. 82 87 */ 83 int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ); 84 85 /** Clears the device specific data. 86 * @param[in] device The device specific data. 87 */ 88 void arp_clear_device( arp_device_ref device ); 88 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address); 89 89 90 90 /** @name Message processing functions … … 103 103 * @returns Other error codes as defined for the measured_strings_return() function. 104 104 */ 105 int arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address ); 106 107 /** Returns the hardware address for the given protocol address. 108 * Sends the ARP request packet if the hardware address is not found in the cache. 105 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address); 106 107 /** Updates the device content length according to the new MTU value. 109 108 * @param[in] device_id The device identifier. 110 * @param[in] protocol The protocol service. 111 * @param[in] target The target protocol address. 112 * @returns The hardware address of the target. 113 * @returns NULL if the target parameter is NULL. 114 * @returns NULL if the device is not found. 115 * @returns NULL if the device packet is too small to send a request. 116 * @returns NULL if the hardware address is not found in the cache. 117 */ 118 measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ); 109 * @param[in] mtu The new mtu value. 110 * @returns ENOENT if device is not found. 111 * @returns EOK on success. 112 */ 113 int arp_mtu_changed_message(device_id_t device_id, size_t mtu); 119 114 120 115 /** Processes the received ARP packet. … … 131 126 * @returns ENOMEM if there is not enough memory left. 132 127 */ 133 int arp_receive_message( device_id_t device_id, packet_t packet ); 134 135 /** Updates the device content length according to the new MTU value. 128 int arp_receive_message(device_id_t device_id, packet_t packet); 129 130 /** Returns the hardware address for the given protocol address. 131 * Sends the ARP request packet if the hardware address is not found in the cache. 136 132 * @param[in] device_id The device identifier. 137 * @param[in] mtu The new mtu value. 138 * @returns ENOENT if device is not found. 139 * @returns EOK on success. 140 */ 141 int arp_mtu_changed_message( device_id_t device_id, size_t mtu ); 133 * @param[in] protocol The protocol service. 134 * @param[in] target The target protocol address. 135 * @returns The hardware address of the target. 136 * @returns NULL if the target parameter is NULL. 137 * @returns NULL if the device is not found. 138 * @returns NULL if the device packet is too small to send a request. 139 * @returns NULL if the hardware address is not found in the cache. 140 */ 141 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target); 142 142 143 143 /*@}*/ 144 144 145 DEVICE_MAP_IMPLEMENT( arp_cache, arp_device_t ) 146 147 INT_MAP_IMPLEMENT( arp_protos, arp_proto_t ) 148 149 GENERIC_CHAR_MAP_IMPLEMENT( arp_addr, measured_string_t ) 150 151 task_id_t arp_task_get_id( void ){ 152 return task_get_id(); 153 } 154 155 int arp_clear_device_req( int arp_phone, device_id_t device_id ){ 156 arp_device_ref device; 157 158 fibril_rwlock_write_lock( & arp_globals.lock ); 159 device = arp_cache_find( & arp_globals.cache, device_id ); 160 if( ! device ){ 161 fibril_rwlock_write_unlock( & arp_globals.lock ); 145 DEVICE_MAP_IMPLEMENT(arp_cache, arp_device_t) 146 147 INT_MAP_IMPLEMENT(arp_protos, arp_proto_t) 148 149 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t) 150 151 int arp_clean_cache_req(int arp_phone){ 152 int count; 153 arp_device_ref device; 154 155 fibril_rwlock_write_lock(&arp_globals.lock); 156 for(count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; -- count){ 157 device = arp_cache_get_index(&arp_globals.cache, count); 158 if(device){ 159 arp_clear_device(device); 160 if(device->addr_data){ 161 free(device->addr_data); 162 } 163 if(device->broadcast_data){ 164 free(device->broadcast_data); 165 } 166 } 167 } 168 arp_cache_clear(&arp_globals.cache); 169 fibril_rwlock_write_unlock(&arp_globals.lock); 170 printf("Cache cleaned\n"); 171 return EOK; 172 } 173 174 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){ 175 arp_device_ref device; 176 arp_proto_ref proto; 177 178 fibril_rwlock_write_lock(&arp_globals.lock); 179 device = arp_cache_find(&arp_globals.cache, device_id); 180 if(! device){ 181 fibril_rwlock_write_unlock(&arp_globals.lock); 162 182 return ENOENT; 163 183 } 164 arp_clear_device( device ); 165 printf( "Device %d cleared\n", device_id ); 166 fibril_rwlock_write_unlock( & arp_globals.lock ); 167 return EOK; 168 } 169 170 int arp_clear_address_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address ){ 171 arp_device_ref device; 172 arp_proto_ref proto; 173 174 fibril_rwlock_write_lock( & arp_globals.lock ); 175 device = arp_cache_find( & arp_globals.cache, device_id ); 176 if( ! device ){ 177 fibril_rwlock_write_unlock( & arp_globals.lock ); 184 proto = arp_protos_find(&device->protos, protocol); 185 if(! proto){ 186 fibril_rwlock_write_unlock(&arp_globals.lock); 178 187 return ENOENT; 179 188 } 180 proto = arp_protos_find( & device->protos, protocol ); 181 if( ! proto ){ 182 fibril_rwlock_write_unlock( & arp_globals.lock ); 189 arp_addr_exclude(&proto->addresses, address->value, address->length); 190 fibril_rwlock_write_unlock(&arp_globals.lock); 191 return EOK; 192 } 193 194 void arp_clear_device(arp_device_ref device){ 195 int count; 196 arp_proto_ref proto; 197 198 for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){ 199 proto = arp_protos_get_index(&device->protos, count); 200 if(proto){ 201 if(proto->addr){ 202 free(proto->addr); 203 } 204 if(proto->addr_data){ 205 free(proto->addr_data); 206 } 207 arp_addr_destroy(&proto->addresses); 208 } 209 } 210 arp_protos_clear(&device->protos); 211 } 212 213 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 214 arp_device_ref device; 215 216 fibril_rwlock_write_lock(&arp_globals.lock); 217 device = arp_cache_find(&arp_globals.cache, device_id); 218 if(! device){ 219 fibril_rwlock_write_unlock(&arp_globals.lock); 183 220 return ENOENT; 184 221 } 185 arp_addr_exclude( & proto->addresses, address->value, address->length ); 186 fibril_rwlock_write_unlock( & arp_globals.lock ); 187 return EOK; 188 } 189 190 int arp_clean_cache_req( int arp_phone ){ 191 int count; 192 arp_device_ref device; 193 194 fibril_rwlock_write_lock( & arp_globals.lock ); 195 for( count = arp_cache_count( & arp_globals.cache ) - 1; count >= 0; -- count ){ 196 device = arp_cache_get_index( & arp_globals.cache, count ); 197 if( device ){ 198 arp_clear_device( device ); 199 if( device->addr_data ) free( device->addr_data ); 200 if( device->broadcast_data ) free( device->broadcast_data ); 201 } 202 } 203 arp_cache_clear( & arp_globals.cache ); 204 fibril_rwlock_write_unlock( & arp_globals.lock ); 205 printf( "Cache cleaned\n" ); 206 return EOK; 207 } 208 209 int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address ){ 222 arp_clear_device(device); 223 printf("Device %d cleared\n", device_id); 224 fibril_rwlock_write_unlock(&arp_globals.lock); 225 return EOK; 226 } 227 228 int arp_connect_module(services_t service){ 229 if(service != SERVICE_ARP){ 230 return EINVAL; 231 } 232 return EOK; 233 } 234 235 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){ 210 236 ERROR_DECLARE; 211 237 212 measured_string_ref tmp; 213 214 // copy the given address for exclusive use 215 tmp = measured_string_copy( address ); 216 if( ERROR_OCCURRED( arp_device_message( device_id, netif, protocol, tmp ))){ 217 free( tmp->value ); 218 free( tmp ); 219 } 220 return ERROR_CODE; 221 } 222 223 int arp_translate_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data ){ 224 measured_string_ref tmp; 225 226 fibril_rwlock_read_lock( & arp_globals.lock ); 227 tmp = arp_translate_message( device_id, protocol, address ); 228 if( tmp ){ 229 * translation = measured_string_copy( tmp ); 230 fibril_rwlock_read_unlock( & arp_globals.lock ); 231 if( * translation ){ 232 * data = ( ** translation ).value; 233 return EOK; 234 }else{ 235 return ENOMEM; 236 } 237 }else{ 238 fibril_rwlock_read_unlock( & arp_globals.lock ); 239 return ENOENT; 240 } 241 } 242 243 int arp_initialize( async_client_conn_t client_connection ){ 244 ERROR_DECLARE; 245 246 fibril_rwlock_initialize( & arp_globals.lock ); 247 fibril_rwlock_write_lock( & arp_globals.lock ); 248 arp_globals.client_connection = client_connection; 249 ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache )); 250 fibril_rwlock_write_unlock( & arp_globals.lock ); 251 return EOK; 252 } 253 254 int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){ 255 ERROR_DECLARE; 256 257 * proto = ( arp_proto_ref ) malloc( sizeof( arp_proto_t )); 258 if( !( * proto )) return ENOMEM; 259 ( ** proto ).service = service; 260 ( ** proto ).addr = address; 261 ( ** proto ).addr_data = address->value; 262 if( ERROR_OCCURRED( arp_addr_initialize( &( ** proto).addresses ))){ 263 free( * proto ); 264 return ERROR_CODE; 265 } 266 return EOK; 267 } 268 269 int arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address ){ 270 ERROR_DECLARE; 271 272 arp_device_ref device; 273 arp_proto_ref proto; 274 int index; 275 hw_type_t hardware; 276 277 fibril_rwlock_write_lock( & arp_globals.lock ); 238 arp_device_ref device; 239 arp_proto_ref proto; 240 int index; 241 hw_type_t hardware; 242 243 fibril_rwlock_write_lock(&arp_globals.lock); 278 244 // an existing device? 279 device = arp_cache_find( & arp_globals.cache, device_id);280 if( device){281 if( device->service != service){282 printf( "Device %d already exists\n", device->device_id);283 fibril_rwlock_write_unlock( & arp_globals.lock);245 device = arp_cache_find(&arp_globals.cache, device_id); 246 if(device){ 247 if(device->service != service){ 248 printf("Device %d already exists\n", device->device_id); 249 fibril_rwlock_write_unlock(&arp_globals.lock); 284 250 return EEXIST; 285 251 } 286 proto = arp_protos_find( & device->protos, protocol);287 if( proto){288 free( proto->addr);289 free( proto->addr_data);252 proto = arp_protos_find(&device->protos, protocol); 253 if(proto){ 254 free(proto->addr); 255 free(proto->addr_data); 290 256 proto->addr = address; 291 257 proto->addr_data = address->value; 292 258 }else{ 293 if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address))){294 fibril_rwlock_write_unlock( & arp_globals.lock);259 if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 260 fibril_rwlock_write_unlock(&arp_globals.lock); 295 261 return ERROR_CODE; 296 262 } 297 index = arp_protos_add( & device->protos, proto->service, proto);298 if( index < 0){299 fibril_rwlock_write_unlock( & arp_globals.lock);300 free( proto);263 index = arp_protos_add(&device->protos, proto->service, proto); 264 if(index < 0){ 265 fibril_rwlock_write_unlock(&arp_globals.lock); 266 free(proto); 301 267 return index; 302 268 } 303 printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol);269 printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol); 304 270 } 305 271 }else{ 306 hardware = hardware_map( service ); 307 if( ! hardware ) return ENOENT; 272 hardware = hardware_map(service); 273 if(! hardware){ 274 return ENOENT; 275 } 308 276 // create a new device 309 device = ( arp_device_ref ) malloc( sizeof( arp_device_t));310 if( ! device){311 fibril_rwlock_write_unlock( & arp_globals.lock);277 device = (arp_device_ref) malloc(sizeof(arp_device_t)); 278 if(! device){ 279 fibril_rwlock_write_unlock(&arp_globals.lock); 312 280 return ENOMEM; 313 281 } 314 282 device->hardware = hardware; 315 283 device->device_id = device_id; 316 if( ERROR_OCCURRED( arp_protos_initialize( & device->protos))317 || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address))){318 fibril_rwlock_write_unlock( & arp_globals.lock);319 free( device);320 return ERROR_CODE; 321 } 322 index = arp_protos_add( & device->protos, proto->service, proto);323 if( index < 0){324 fibril_rwlock_write_unlock( & arp_globals.lock);325 arp_protos_destroy( & device->protos);326 free( device);284 if(ERROR_OCCURRED(arp_protos_initialize(&device->protos)) 285 || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 286 fibril_rwlock_write_unlock(&arp_globals.lock); 287 free(device); 288 return ERROR_CODE; 289 } 290 index = arp_protos_add(&device->protos, proto->service, proto); 291 if(index < 0){ 292 fibril_rwlock_write_unlock(&arp_globals.lock); 293 arp_protos_destroy(&device->protos); 294 free(device); 327 295 return index; 328 296 } 329 297 device->service = service; 330 298 // bind the new one 331 device->phone = nil_bind_service( device->service, ( ipcarg_t ) device->device_id, SERVICE_ARP, arp_globals.client_connection);332 if( device->phone < 0){333 fibril_rwlock_write_unlock( & arp_globals.lock);334 arp_protos_destroy( & device->protos);335 free( device);299 device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection); 300 if(device->phone < 0){ 301 fibril_rwlock_write_unlock(&arp_globals.lock); 302 arp_protos_destroy(&device->protos); 303 free(device); 336 304 return EREFUSED; 337 305 } 338 306 // get packet dimensions 339 if( ERROR_OCCURRED( nil_packet_size_req( device->phone, device_id, & device->packet_dimension))){340 fibril_rwlock_write_unlock( & arp_globals.lock);341 arp_protos_destroy( & device->protos);342 free( device);307 if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){ 308 fibril_rwlock_write_unlock(&arp_globals.lock); 309 arp_protos_destroy(&device->protos); 310 free(device); 343 311 return ERROR_CODE; 344 312 } 345 313 // get hardware address 346 if( ERROR_OCCURRED( nil_get_addr_req( device->phone, device_id, & device->addr, & device->addr_data))){347 fibril_rwlock_write_unlock( & arp_globals.lock);348 arp_protos_destroy( & device->protos);349 free( device);314 if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){ 315 fibril_rwlock_write_unlock(&arp_globals.lock); 316 arp_protos_destroy(&device->protos); 317 free(device); 350 318 return ERROR_CODE; 351 319 } 352 320 // get broadcast address 353 if( ERROR_OCCURRED( nil_get_broadcast_addr_req( device->phone, device_id, & device->broadcast_addr, & device->broadcast_data ))){ 354 fibril_rwlock_write_unlock( & arp_globals.lock ); 355 free( device->addr ); 356 free( device->addr_data ); 357 arp_protos_destroy( & device->protos ); 358 free( device ); 359 return ERROR_CODE; 360 } 361 if( ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){ 362 fibril_rwlock_write_unlock( & arp_globals.lock ); 363 free( device->addr ); 364 free( device->addr_data ); 365 free( device->broadcast_addr ); 366 free( device->broadcast_data ); 367 arp_protos_destroy( & device->protos ); 368 free( device ); 369 return ERROR_CODE; 370 } 371 printf( "New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol ); 372 } 373 fibril_rwlock_write_unlock( & arp_globals.lock ); 374 return EOK; 375 } 376 377 measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){ 378 arp_device_ref device; 379 arp_proto_ref proto; 380 measured_string_ref addr; 381 size_t length; 382 packet_t packet; 383 arp_header_ref header; 384 385 if( ! target ) return NULL; 386 device = arp_cache_find( & arp_globals.cache, device_id ); 387 if( ! device ) return NULL; 388 proto = arp_protos_find( & device->protos, protocol ); 389 if(( ! proto ) || ( proto->addr->length != target->length )) return NULL; 390 addr = arp_addr_find( & proto->addresses, target->value, target->length ); 391 if( addr ) return addr; 392 // ARP packet content size = header + ( address + translation ) * 2 393 length = 8 + ( CONVERT_SIZE( char, uint8_t, proto->addr->length ) + CONVERT_SIZE( char, uint8_t, device->addr->length )) * 2; 394 if( length > device->packet_dimension.content ) return NULL; 395 packet = packet_get_4( arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix ); 396 if( ! packet ) return NULL; 397 header = ( arp_header_ref ) packet_suffix( packet, length ); 398 if( ! header ){ 399 pq_release( arp_globals.net_phone, packet_get_id( packet )); 400 return NULL; 401 } 402 header->hardware = htons( device->hardware ); 403 header->hardware_length = ( uint8_t ) device->addr->length; 404 header->protocol = htons( protocol_map( device->service, protocol )); 405 header->protocol_length = ( uint8_t ) proto->addr->length; 406 header->operation = htons( ARPOP_REQUEST ); 407 length = sizeof( arp_header_t ); 408 memcpy((( uint8_t * ) header ) + length, device->addr->value, device->addr->length ); 409 length += device->addr->length; 410 memcpy((( uint8_t * ) header ) + length, proto->addr->value, proto->addr->length ); 411 length += proto->addr->length; 412 bzero((( uint8_t * ) header ) + length, device->addr->length ); 413 length += device->addr->length; 414 memcpy((( uint8_t * ) header ) + length, target->value, target->length ); 415 if( packet_set_addr( packet, ( uint8_t * ) device->addr->value, ( uint8_t * ) device->broadcast_addr->value, CONVERT_SIZE( char, uint8_t, device->addr->length )) != EOK ){ 416 pq_release( arp_globals.net_phone, packet_get_id( packet )); 417 return NULL; 418 } 419 nil_send_msg( device->phone, device_id, packet, SERVICE_ARP ); 420 return NULL; 421 } 422 423 int arp_receive_message( device_id_t device_id, packet_t packet ){ 321 if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){ 322 fibril_rwlock_write_unlock(&arp_globals.lock); 323 free(device->addr); 324 free(device->addr_data); 325 arp_protos_destroy(&device->protos); 326 free(device); 327 return ERROR_CODE; 328 } 329 if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){ 330 fibril_rwlock_write_unlock(&arp_globals.lock); 331 free(device->addr); 332 free(device->addr_data); 333 free(device->broadcast_addr); 334 free(device->broadcast_data); 335 arp_protos_destroy(&device->protos); 336 free(device); 337 return ERROR_CODE; 338 } 339 printf("New device registered:\n\tid\t= %d\n\ttype\t= 0x%x\n\tservice\t= %d\n\tproto\t= %d\n", device->device_id, device->hardware, device->service, protocol); 340 } 341 fibril_rwlock_write_unlock(&arp_globals.lock); 342 return EOK; 343 } 344 345 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 424 346 ERROR_DECLARE; 425 347 426 size_t length; 427 arp_header_ref header; 428 arp_device_ref device; 429 arp_proto_ref proto; 430 measured_string_ref hw_source; 431 uint8_t * src_hw; 432 uint8_t * src_proto; 433 uint8_t * des_hw; 434 uint8_t * des_proto; 435 436 length = packet_get_data_length( packet ); 437 if( length <= sizeof( arp_header_t )) return EINVAL; 438 device = arp_cache_find( & arp_globals.cache, device_id ); 439 if( ! device ) return ENOENT; 440 header = ( arp_header_ref ) packet_get_data( packet ); 441 if(( ntohs( header->hardware ) != device->hardware ) 442 || ( length < sizeof( arp_header_t ) + header->hardware_length * 2u + header->protocol_length * 2u )){ 443 return EINVAL; 444 } 445 proto = arp_protos_find( & device->protos, protocol_unmap( device->service, ntohs( header->protocol ))); 446 if( ! proto ) return ENOENT; 447 src_hw = (( uint8_t * ) header ) + sizeof( arp_header_t ); 448 src_proto = src_hw + header->hardware_length; 449 des_hw = src_proto + header->protocol_length; 450 des_proto = des_hw + header->hardware_length; 451 hw_source = arp_addr_find( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length )); 452 // exists? 453 if( hw_source ){ 454 if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){ 455 return EINVAL; 456 } 457 memcpy( hw_source->value, src_hw, hw_source->length ); 458 } 459 // is my protocol address? 460 if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->protocol_length )){ 461 return EINVAL; 462 } 463 if( ! str_lcmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){ 464 // not already upadted? 465 if( ! hw_source ){ 466 hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length )); 467 if( ! hw_source ) return ENOMEM; 468 ERROR_PROPAGATE( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source )); 469 } 470 if( ntohs( header->operation ) == ARPOP_REQUEST ){ 471 header->operation = htons( ARPOP_REPLY ); 472 memcpy( des_proto, src_proto, header->protocol_length ); 473 memcpy( src_proto, proto->addr->value, header->protocol_length ); 474 memcpy( src_hw, device->addr->value, device->packet_dimension.addr_len ); 475 memcpy( des_hw, hw_source->value, header->hardware_length ); 476 ERROR_PROPAGATE( packet_set_addr( packet, src_hw, des_hw, header->hardware_length )); 477 nil_send_msg( device->phone, device_id, packet, SERVICE_ARP ); 478 return 1; 479 } 480 } 481 return EOK; 482 } 483 484 void arp_clear_device( arp_device_ref device ){ 485 int count; 486 arp_proto_ref proto; 487 488 for( count = arp_protos_count( & device->protos ) - 1; count >= 0; -- count ){ 489 proto = arp_protos_get_index( & device->protos, count ); 490 if( proto ){ 491 if( proto->addr ) free( proto->addr ); 492 if( proto->addr_data ) free( proto->addr_data ); 493 arp_addr_destroy( & proto->addresses ); 494 } 495 } 496 arp_protos_clear( & device->protos ); 497 } 498 499 int arp_connect_module( services_t service ){ 500 if( service != SERVICE_ARP ) return EINVAL; 501 return EOK; 502 } 503 504 int arp_mtu_changed_message( device_id_t device_id, size_t mtu ){ 505 arp_device_ref device; 506 507 fibril_rwlock_write_lock( & arp_globals.lock ); 508 device = arp_cache_find( & arp_globals.cache, device_id ); 509 if( ! device ){ 510 fibril_rwlock_write_unlock( & arp_globals.lock ); 511 return ENOENT; 512 } 513 device->packet_dimension.content = mtu; 514 printf( "arp - device %d changed mtu to %d\n\n", device_id, mtu ); 515 fibril_rwlock_write_unlock( & arp_globals.lock ); 516 return EOK; 517 } 518 519 int arp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ 348 measured_string_ref tmp; 349 350 // copy the given address for exclusive use 351 tmp = measured_string_copy(address); 352 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){ 353 free(tmp->value); 354 free(tmp); 355 } 356 return ERROR_CODE; 357 } 358 359 int arp_initialize(async_client_conn_t client_connection){ 520 360 ERROR_DECLARE; 521 361 522 measured_string_ref address; 523 measured_string_ref translation; 524 char * data; 525 packet_t packet; 526 packet_t next; 527 528 // printf( "message %d - %d\n", IPC_GET_METHOD( * call ), NET_ARP_FIRST ); 529 * answer_count = 0; 530 switch( IPC_GET_METHOD( * call )){ 362 fibril_rwlock_initialize(&arp_globals.lock); 363 fibril_rwlock_write_lock(&arp_globals.lock); 364 arp_globals.client_connection = client_connection; 365 ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache)); 366 fibril_rwlock_write_unlock(&arp_globals.lock); 367 return EOK; 368 } 369 370 int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 371 ERROR_DECLARE; 372 373 measured_string_ref address; 374 measured_string_ref translation; 375 char * data; 376 packet_t packet; 377 packet_t next; 378 379 // printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_ARP_FIRST); 380 *answer_count = 0; 381 switch(IPC_GET_METHOD(*call)){ 531 382 case IPC_M_PHONE_HUNGUP: 532 383 return EOK; 533 384 case NET_ARP_DEVICE: 534 ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1));535 if( ERROR_OCCURRED( arp_device_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), ARP_GET_NETIF( call ), address))){536 free( address);537 free( data);385 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 386 if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){ 387 free(address); 388 free(data); 538 389 } 539 390 return ERROR_CODE; 540 391 case NET_ARP_TRANSLATE: 541 ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1));542 fibril_rwlock_read_lock( & arp_globals.lock);543 translation = arp_translate_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address);544 free( address);545 free( data);546 if( ! translation){547 fibril_rwlock_read_unlock( & arp_globals.lock);392 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 393 fibril_rwlock_read_lock(&arp_globals.lock); 394 translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 395 free(address); 396 free(data); 397 if(! translation){ 398 fibril_rwlock_read_unlock(&arp_globals.lock); 548 399 return ENOENT; 549 400 } 550 ERROR_CODE = measured_strings_reply( translation, 1);551 fibril_rwlock_read_unlock( & arp_globals.lock);401 ERROR_CODE = measured_strings_reply(translation, 1); 402 fibril_rwlock_read_unlock(&arp_globals.lock); 552 403 return ERROR_CODE; 553 404 case NET_ARP_CLEAR_DEVICE: 554 return arp_clear_device_req( 0, IPC_GET_DEVICE( call));405 return arp_clear_device_req(0, IPC_GET_DEVICE(call)); 555 406 case NET_ARP_CLEAR_ADDRESS: 556 ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1));557 arp_clear_address_req( 0, IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address);558 free( address);559 free( data);407 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 408 arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 409 free(address); 410 free(data); 560 411 return EOK; 561 412 case NET_ARP_CLEAN_CACHE: 562 return arp_clean_cache_req( 0);413 return arp_clean_cache_req(0); 563 414 case NET_IL_DEVICE_STATE: 564 415 // do nothing - keep the cache 565 416 return EOK; 566 417 case NET_IL_RECEIVED: 567 if( ! ERROR_OCCURRED( packet_translate( arp_globals.net_phone, & packet, IPC_GET_PACKET( call)))){568 fibril_rwlock_read_lock( & arp_globals.lock);418 if(! ERROR_OCCURRED(packet_translate(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 419 fibril_rwlock_read_lock(&arp_globals.lock); 569 420 do{ 570 next = pq_detach( packet ); 571 ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( call ), packet ); 572 if( ERROR_CODE != 1 ) pq_release( arp_globals.net_phone, packet_get_id( packet )); 421 next = pq_detach(packet); 422 ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet); 423 if(ERROR_CODE != 1){ 424 pq_release(arp_globals.net_phone, packet_get_id(packet)); 425 } 573 426 packet = next; 574 }while( packet);575 fibril_rwlock_read_unlock( & arp_globals.lock);427 }while(packet); 428 fibril_rwlock_read_unlock(&arp_globals.lock); 576 429 } 577 430 return ERROR_CODE; 578 431 case NET_IL_MTU_CHANGED: 579 return arp_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call));432 return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call)); 580 433 } 581 434 return ENOTSUP; 582 435 } 583 436 437 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){ 438 arp_device_ref device; 439 440 fibril_rwlock_write_lock(&arp_globals.lock); 441 device = arp_cache_find(&arp_globals.cache, device_id); 442 if(! device){ 443 fibril_rwlock_write_unlock(&arp_globals.lock); 444 return ENOENT; 445 } 446 device->packet_dimension.content = mtu; 447 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu); 448 fibril_rwlock_write_unlock(&arp_globals.lock); 449 return EOK; 450 } 451 452 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){ 453 ERROR_DECLARE; 454 455 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 456 if(!(*proto)){ 457 return ENOMEM; 458 } 459 (** proto).service = service; 460 (** proto).addr = address; 461 (** proto).addr_data = address->value; 462 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){ 463 free(*proto); 464 return ERROR_CODE; 465 } 466 return EOK; 467 } 468 469 int arp_receive_message(device_id_t device_id, packet_t packet){ 470 ERROR_DECLARE; 471 472 size_t length; 473 arp_header_ref header; 474 arp_device_ref device; 475 arp_proto_ref proto; 476 measured_string_ref hw_source; 477 uint8_t * src_hw; 478 uint8_t * src_proto; 479 uint8_t * des_hw; 480 uint8_t * des_proto; 481 482 length = packet_get_data_length(packet); 483 if(length <= sizeof(arp_header_t)){ 484 return EINVAL; 485 } 486 device = arp_cache_find(&arp_globals.cache, device_id); 487 if(! device){ 488 return ENOENT; 489 } 490 header = (arp_header_ref) packet_get_data(packet); 491 if((ntohs(header->hardware) != device->hardware) 492 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){ 493 return EINVAL; 494 } 495 proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol))); 496 if(! proto){ 497 return ENOENT; 498 } 499 src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 500 src_proto = src_hw + header->hardware_length; 501 des_hw = src_proto + header->protocol_length; 502 des_proto = des_hw + header->hardware_length; 503 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length)); 504 // exists? 505 if(hw_source){ 506 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){ 507 return EINVAL; 508 } 509 memcpy(hw_source->value, src_hw, hw_source->length); 510 } 511 // is my protocol address? 512 if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){ 513 return EINVAL; 514 } 515 if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){ 516 // not already upadted? 517 if(! hw_source){ 518 hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length)); 519 if(! hw_source){ 520 return ENOMEM; 521 } 522 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source)); 523 } 524 if(ntohs(header->operation) == ARPOP_REQUEST){ 525 header->operation = htons(ARPOP_REPLY); 526 memcpy(des_proto, src_proto, header->protocol_length); 527 memcpy(src_proto, proto->addr->value, header->protocol_length); 528 memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len); 529 memcpy(des_hw, hw_source->value, header->hardware_length); 530 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length)); 531 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 532 return 1; 533 } 534 } 535 return EOK; 536 } 537 538 task_id_t arp_task_get_id(void){ 539 return task_get_id(); 540 } 541 542 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){ 543 arp_device_ref device; 544 arp_proto_ref proto; 545 measured_string_ref addr; 546 size_t length; 547 packet_t packet; 548 arp_header_ref header; 549 550 if(! target){ 551 return NULL; 552 } 553 device = arp_cache_find(&arp_globals.cache, device_id); 554 if(! device){ 555 return NULL; 556 } 557 proto = arp_protos_find(&device->protos, protocol); 558 if((! proto) || (proto->addr->length != target->length)){ 559 return NULL; 560 } 561 addr = arp_addr_find(&proto->addresses, target->value, target->length); 562 if(addr){ 563 return addr; 564 } 565 // ARP packet content size = header + (address + translation) * 2 566 length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2; 567 if(length > device->packet_dimension.content){ 568 return NULL; 569 } 570 packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix); 571 if(! packet){ 572 return NULL; 573 } 574 header = (arp_header_ref) packet_suffix(packet, length); 575 if(! header){ 576 pq_release(arp_globals.net_phone, packet_get_id(packet)); 577 return NULL; 578 } 579 header->hardware = htons(device->hardware); 580 header->hardware_length = (uint8_t) device->addr->length; 581 header->protocol = htons(protocol_map(device->service, protocol)); 582 header->protocol_length = (uint8_t) proto->addr->length; 583 header->operation = htons(ARPOP_REQUEST); 584 length = sizeof(arp_header_t); 585 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length); 586 length += device->addr->length; 587 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length); 588 length += proto->addr->length; 589 bzero(((uint8_t *) header) + length, device->addr->length); 590 length += device->addr->length; 591 memcpy(((uint8_t *) header) + length, target->value, target->length); 592 if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){ 593 pq_release(arp_globals.net_phone, packet_get_id(packet)); 594 return NULL; 595 } 596 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 597 return NULL; 598 } 599 600 int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){ 601 measured_string_ref tmp; 602 603 fibril_rwlock_read_lock(&arp_globals.lock); 604 tmp = arp_translate_message(device_id, protocol, address); 605 if(tmp){ 606 *translation = measured_string_copy(tmp); 607 fibril_rwlock_read_unlock(&arp_globals.lock); 608 if(*translation){ 609 *data = (** translation).value; 610 return EOK; 611 }else{ 612 return ENOMEM; 613 } 614 }else{ 615 fibril_rwlock_read_unlock(&arp_globals.lock); 616 return ENOENT; 617 } 618 } 619 584 620 /** @} 585 621 */
Note:
See TracChangeset
for help on using the changeset viewer.