Changeset aadf01e in mainline for uspace/srv/net/il/arp
- Timestamp:
- 2010-03-07T15:13:28Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 936835e
- Parents:
- aa85487
- Location:
- uspace/srv/net/il/arp
- Files:
-
- 7 edited
-
arp.c (modified) (9 diffs)
-
arp.h (modified) (6 diffs)
-
arp_header.h (modified) (1 diff)
-
arp_messages.h (modified) (1 diff)
-
arp_module.c (modified) (5 diffs)
-
arp_module.h (modified) (2 diffs)
-
arp_remote.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/arp/arp.c
raa85487 raadf01e 81 81 * @returns ENOMEM if there is not enough memory left. 82 82 */ 83 int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address);83 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address); 84 84 85 85 /** Clears the device specific data. 86 86 * @param[in] device The device specific data. 87 87 */ 88 void arp_clear_device( arp_device_ref device);88 void arp_clear_device(arp_device_ref device); 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);105 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address); 106 106 107 107 /** Returns the hardware address for the given protocol address. … … 116 116 * @returns NULL if the hardware address is not found in the cache. 117 117 */ 118 measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target);118 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target); 119 119 120 120 /** Processes the received ARP packet. … … 131 131 * @returns ENOMEM if there is not enough memory left. 132 132 */ 133 int arp_receive_message( device_id_t device_id, packet_t packet);133 int arp_receive_message(device_id_t device_id, packet_t packet); 134 134 135 135 /** Updates the device content length according to the new MTU value. … … 139 139 * @returns EOK on success. 140 140 */ 141 int arp_mtu_changed_message( device_id_t device_id, size_t mtu);141 int arp_mtu_changed_message(device_id_t device_id, size_t mtu); 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){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 152 return task_get_id(); 153 153 } 154 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);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); 162 162 return ENOENT; 163 163 } 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);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); 178 178 return ENOENT; 179 179 } 180 proto = arp_protos_find( & device->protos, protocol);181 if( ! proto){182 fibril_rwlock_write_unlock( & arp_globals.lock);180 proto = arp_protos_find(&device->protos, protocol); 181 if(! proto){ 182 fibril_rwlock_write_unlock(&arp_globals.lock); 183 183 return ENOENT; 184 184 } 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 ){ 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){ 200 free(device->addr_data); 201 } 202 if(device->broadcast_data){ 203 free(device->broadcast_data); 204 } 205 } 206 } 207 arp_cache_clear(&arp_globals.cache); 208 fibril_rwlock_write_unlock(&arp_globals.lock); 209 printf("Cache cleaned\n"); 210 return EOK; 211 } 212 213 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 210 214 ERROR_DECLARE; 211 215 … … 213 217 214 218 // 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 tmp = measured_string_copy(address); 220 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){ 221 free(tmp->value); 222 free(tmp); 219 223 } 220 224 return ERROR_CODE; 221 225 } 222 226 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;227 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){ 228 measured_string_ref tmp; 229 230 fibril_rwlock_read_lock(&arp_globals.lock); 231 tmp = arp_translate_message(device_id, protocol, address); 232 if(tmp){ 233 *translation = measured_string_copy(tmp); 234 fibril_rwlock_read_unlock(&arp_globals.lock); 235 if(*translation){ 236 *data = (** translation).value; 233 237 return EOK; 234 238 }else{ … … 236 240 } 237 241 }else{ 238 fibril_rwlock_read_unlock( & arp_globals.lock);242 fibril_rwlock_read_unlock(&arp_globals.lock); 239 243 return ENOENT; 240 244 } 241 245 } 242 246 243 int arp_initialize( async_client_conn_t client_connection){247 int arp_initialize(async_client_conn_t client_connection){ 244 248 ERROR_DECLARE; 245 249 246 fibril_rwlock_initialize( & arp_globals.lock);247 fibril_rwlock_write_lock( & arp_globals.lock);250 fibril_rwlock_initialize(&arp_globals.lock); 251 fibril_rwlock_write_lock(&arp_globals.lock); 248 252 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){253 ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache)); 254 fibril_rwlock_write_unlock(&arp_globals.lock); 255 return EOK; 256 } 257 258 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){ 255 259 ERROR_DECLARE; 256 260 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 ); 261 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 262 if(!(*proto)){ 263 return ENOMEM; 264 } 265 (** proto).service = service; 266 (** proto).addr = address; 267 (** proto).addr_data = address->value; 268 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){ 269 free(*proto); 264 270 return ERROR_CODE; 265 271 } … … 267 273 } 268 274 269 int arp_device_message( device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){275 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address){ 270 276 ERROR_DECLARE; 271 277 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);278 arp_device_ref device; 279 arp_proto_ref proto; 280 int index; 281 hw_type_t hardware; 282 283 fibril_rwlock_write_lock(&arp_globals.lock); 278 284 // 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);285 device = arp_cache_find(&arp_globals.cache, device_id); 286 if(device){ 287 if(device->service != service){ 288 printf("Device %d already exists\n", device->device_id); 289 fibril_rwlock_write_unlock(&arp_globals.lock); 284 290 return EEXIST; 285 291 } 286 proto = arp_protos_find( & device->protos, protocol);287 if( proto){288 free( proto->addr);289 free( proto->addr_data);292 proto = arp_protos_find(&device->protos, protocol); 293 if(proto){ 294 free(proto->addr); 295 free(proto->addr_data); 290 296 proto->addr = address; 291 297 proto->addr_data = address->value; 292 298 }else{ 293 if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address))){294 fibril_rwlock_write_unlock( & arp_globals.lock);299 if(ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 300 fibril_rwlock_write_unlock(&arp_globals.lock); 295 301 return ERROR_CODE; 296 302 } 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);303 index = arp_protos_add(&device->protos, proto->service, proto); 304 if(index < 0){ 305 fibril_rwlock_write_unlock(&arp_globals.lock); 306 free(proto); 301 307 return index; 302 308 } 303 printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol);309 printf("New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol); 304 310 } 305 311 }else{ 306 hardware = hardware_map( service ); 307 if( ! hardware ) return ENOENT; 312 hardware = hardware_map(service); 313 if(! hardware){ 314 return ENOENT; 315 } 308 316 // 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);317 device = (arp_device_ref) malloc(sizeof(arp_device_t)); 318 if(! device){ 319 fibril_rwlock_write_unlock(&arp_globals.lock); 312 320 return ENOMEM; 313 321 } 314 322 device->hardware = hardware; 315 323 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);324 if(ERROR_OCCURRED(arp_protos_initialize(&device->protos)) 325 || ERROR_OCCURRED(arp_proto_create(&proto, protocol, address))){ 326 fibril_rwlock_write_unlock(&arp_globals.lock); 327 free(device); 328 return ERROR_CODE; 329 } 330 index = arp_protos_add(&device->protos, proto->service, proto); 331 if(index < 0){ 332 fibril_rwlock_write_unlock(&arp_globals.lock); 333 arp_protos_destroy(&device->protos); 334 free(device); 327 335 return index; 328 336 } 329 337 device->service = service; 330 338 // 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);339 device->phone = nil_bind_service(device->service, (ipcarg_t) device->device_id, SERVICE_ARP, arp_globals.client_connection); 340 if(device->phone < 0){ 341 fibril_rwlock_write_unlock(&arp_globals.lock); 342 arp_protos_destroy(&device->protos); 343 free(device); 336 344 return EREFUSED; 337 345 } 338 346 // 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);347 if(ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, &device->packet_dimension))){ 348 fibril_rwlock_write_unlock(&arp_globals.lock); 349 arp_protos_destroy(&device->protos); 350 free(device); 343 351 return ERROR_CODE; 344 352 } 345 353 // 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);354 if(ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, &device->addr, &device->addr_data))){ 355 fibril_rwlock_write_unlock(&arp_globals.lock); 356 arp_protos_destroy(&device->protos); 357 free(device); 350 358 return ERROR_CODE; 351 359 } 352 360 // 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 )); 361 if(ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone, device_id, &device->broadcast_addr, &device->broadcast_data))){ 362 fibril_rwlock_write_unlock(&arp_globals.lock); 363 free(device->addr); 364 free(device->addr_data); 365 arp_protos_destroy(&device->protos); 366 free(device); 367 return ERROR_CODE; 368 } 369 if(ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, device->device_id, device))){ 370 fibril_rwlock_write_unlock(&arp_globals.lock); 371 free(device->addr); 372 free(device->addr_data); 373 free(device->broadcast_addr); 374 free(device->broadcast_data); 375 arp_protos_destroy(&device->protos); 376 free(device); 377 return ERROR_CODE; 378 } 379 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); 380 } 381 fibril_rwlock_write_unlock(&arp_globals.lock); 382 return EOK; 383 } 384 385 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){ 386 arp_device_ref device; 387 arp_proto_ref proto; 388 measured_string_ref addr; 389 size_t length; 390 packet_t packet; 391 arp_header_ref header; 392 393 if(! target){ 400 394 return NULL; 401 395 } 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 ); 396 device = arp_cache_find(&arp_globals.cache, device_id); 397 if(! device){ 398 return NULL; 399 } 400 proto = arp_protos_find(&device->protos, protocol); 401 if((! proto) || (proto->addr->length != target->length)){ 402 return NULL; 403 } 404 addr = arp_addr_find(&proto->addresses, target->value, target->length); 405 if(addr){ 406 return addr; 407 } 408 // ARP packet content size = header + (address + translation) * 2 409 length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2; 410 if(length > device->packet_dimension.content){ 411 return NULL; 412 } 413 packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix); 414 if(! packet){ 415 return NULL; 416 } 417 header = (arp_header_ref) packet_suffix(packet, length); 418 if(! header){ 419 pq_release(arp_globals.net_phone, packet_get_id(packet)); 420 return NULL; 421 } 422 header->hardware = htons(device->hardware); 423 header->hardware_length = (uint8_t) device->addr->length; 424 header->protocol = htons(protocol_map(device->service, protocol)); 425 header->protocol_length = (uint8_t) proto->addr->length; 426 header->operation = htons(ARPOP_REQUEST); 427 length = sizeof(arp_header_t); 428 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length); 409 429 length += device->addr->length; 410 memcpy((( uint8_t * ) header ) + length, proto->addr->value, proto->addr->length);430 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length); 411 431 length += proto->addr->length; 412 bzero((( uint8_t * ) header ) + length, device->addr->length);432 bzero(((uint8_t *) header) + length, device->addr->length); 413 433 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));434 memcpy(((uint8_t *) header) + length, target->value, target->length); 435 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){ 436 pq_release(arp_globals.net_phone, packet_get_id(packet)); 417 437 return NULL; 418 438 } 419 nil_send_msg( device->phone, device_id, packet, SERVICE_ARP);439 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 420 440 return NULL; 421 441 } 422 442 423 int arp_receive_message( device_id_t device_id, packet_t packet){443 int arp_receive_message(device_id_t device_id, packet_t packet){ 424 444 ERROR_DECLARE; 425 445 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 )){ 446 size_t length; 447 arp_header_ref header; 448 arp_device_ref device; 449 arp_proto_ref proto; 450 measured_string_ref hw_source; 451 uint8_t * src_hw; 452 uint8_t * src_proto; 453 uint8_t * des_hw; 454 uint8_t * des_proto; 455 456 length = packet_get_data_length(packet); 457 if(length <= sizeof(arp_header_t)){ 443 458 return EINVAL; 444 459 } 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 ); 460 device = arp_cache_find(&arp_globals.cache, device_id); 461 if(! device){ 462 return ENOENT; 463 } 464 header = (arp_header_ref) packet_get_data(packet); 465 if((ntohs(header->hardware) != device->hardware) 466 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){ 467 return EINVAL; 468 } 469 proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol))); 470 if(! proto){ 471 return ENOENT; 472 } 473 src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 448 474 src_proto = src_hw + header->hardware_length; 449 475 des_hw = src_proto + header->protocol_length; 450 476 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));477 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length)); 452 478 // exists? 453 if( hw_source){454 if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length)){479 if(hw_source){ 480 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){ 455 481 return EINVAL; 456 482 } 457 memcpy( hw_source->value, src_hw, hw_source->length);483 memcpy(hw_source->value, src_hw, hw_source->length); 458 484 } 459 485 // is my protocol address? 460 if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->protocol_length)){486 if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){ 461 487 return EINVAL; 462 488 } 463 if( ! str_lcmp( proto->addr->value, ( char * ) des_proto, proto->addr->length)){489 if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){ 464 490 // 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 ); 491 if(! hw_source){ 492 hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length)); 493 if(! hw_source){ 494 return ENOMEM; 495 } 496 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source)); 497 } 498 if(ntohs(header->operation) == ARPOP_REQUEST){ 499 header->operation = htons(ARPOP_REPLY); 500 memcpy(des_proto, src_proto, header->protocol_length); 501 memcpy(src_proto, proto->addr->value, header->protocol_length); 502 memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len); 503 memcpy(des_hw, hw_source->value, header->hardware_length); 504 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length)); 505 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 478 506 return 1; 479 507 } … … 482 510 } 483 511 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 ); 512 void arp_clear_device(arp_device_ref device){ 513 int count; 514 arp_proto_ref proto; 515 516 for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){ 517 proto = arp_protos_get_index(&device->protos, count); 518 if(proto){ 519 if(proto->addr){ 520 free(proto->addr); 521 } 522 if(proto->addr_data){ 523 free(proto->addr_data); 524 } 525 arp_addr_destroy(&proto->addresses); 526 } 527 } 528 arp_protos_clear(&device->protos); 529 } 530 531 int arp_connect_module(services_t service){ 532 if(service != SERVICE_ARP){ 533 return EINVAL; 534 } 535 return EOK; 536 } 537 538 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){ 539 arp_device_ref device; 540 541 fibril_rwlock_write_lock(&arp_globals.lock); 542 device = arp_cache_find(&arp_globals.cache, device_id); 543 if(! device){ 544 fibril_rwlock_write_unlock(&arp_globals.lock); 511 545 return ENOENT; 512 546 } 513 547 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){548 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu); 549 fibril_rwlock_write_unlock(&arp_globals.lock); 550 return EOK; 551 } 552 553 int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 520 554 ERROR_DECLARE; 521 555 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)){556 measured_string_ref address; 557 measured_string_ref translation; 558 char * data; 559 packet_t packet; 560 packet_t next; 561 562 // printf("message %d - %d\n", IPC_GET_METHOD(*call), NET_ARP_FIRST); 563 *answer_count = 0; 564 switch(IPC_GET_METHOD(*call)){ 531 565 case IPC_M_PHONE_HUNGUP: 532 566 return EOK; 533 567 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);568 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 569 if(ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))){ 570 free(address); 571 free(data); 538 572 } 539 573 return ERROR_CODE; 540 574 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);575 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 576 fibril_rwlock_read_lock(&arp_globals.lock); 577 translation = arp_translate_message(IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 578 free(address); 579 free(data); 580 if(! translation){ 581 fibril_rwlock_read_unlock(&arp_globals.lock); 548 582 return ENOENT; 549 583 } 550 ERROR_CODE = measured_strings_reply( translation, 1);551 fibril_rwlock_read_unlock( & arp_globals.lock);584 ERROR_CODE = measured_strings_reply(translation, 1); 585 fibril_rwlock_read_unlock(&arp_globals.lock); 552 586 return ERROR_CODE; 553 587 case NET_ARP_CLEAR_DEVICE: 554 return arp_clear_device_req( 0, IPC_GET_DEVICE( call));588 return arp_clear_device_req(0, IPC_GET_DEVICE(call)); 555 589 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);590 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 591 arp_clear_address_req(0, IPC_GET_DEVICE(call), IPC_GET_SERVICE(call), address); 592 free(address); 593 free(data); 560 594 return EOK; 561 595 case NET_ARP_CLEAN_CACHE: 562 return arp_clean_cache_req( 0);596 return arp_clean_cache_req(0); 563 597 case NET_IL_DEVICE_STATE: 564 598 // do nothing - keep the cache 565 599 return EOK; 566 600 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);601 if(! ERROR_OCCURRED(packet_translate(arp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 602 fibril_rwlock_read_lock(&arp_globals.lock); 569 603 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 )); 604 next = pq_detach(packet); 605 ERROR_CODE = arp_receive_message(IPC_GET_DEVICE(call), packet); 606 if(ERROR_CODE != 1){ 607 pq_release(arp_globals.net_phone, packet_get_id(packet)); 608 } 573 609 packet = next; 574 }while( packet);575 fibril_rwlock_read_unlock( & arp_globals.lock);610 }while(packet); 611 fibril_rwlock_read_unlock(&arp_globals.lock); 576 612 } 577 613 return ERROR_CODE; 578 614 case NET_IL_MTU_CHANGED: 579 return arp_mtu_changed_message( IPC_GET_DEVICE( call ), IPC_GET_MTU( call));615 return arp_mtu_changed_message(IPC_GET_DEVICE(call), IPC_GET_MTU(call)); 580 616 } 581 617 return ENOTSUP; -
uspace/srv/net/il/arp/arp.h
raa85487 raadf01e 80 80 * @see device.h 81 81 */ 82 DEVICE_MAP_DECLARE( arp_cache, arp_device_t)82 DEVICE_MAP_DECLARE(arp_cache, arp_device_t) 83 83 84 84 /** ARP protocol map. … … 86 86 * @see int_map.h 87 87 */ 88 INT_MAP_DECLARE( arp_protos, arp_proto_t)88 INT_MAP_DECLARE(arp_protos, arp_proto_t) 89 89 90 90 /** ARP address map. … … 92 92 * @see generic_char_map.h 93 93 */ 94 GENERIC_CHAR_MAP_DECLARE( arp_addr, measured_string_t)94 GENERIC_CHAR_MAP_DECLARE(arp_addr, measured_string_t) 95 95 96 96 /** ARP device specific data. … … 99 99 /** Device identifier. 100 100 */ 101 device_id_t device_id;101 device_id_t device_id; 102 102 /** Hardware type. 103 103 */ 104 hw_type_t hardware;104 hw_type_t hardware; 105 105 /** Packet dimension. 106 106 */ 107 packet_dimension_t packet_dimension;107 packet_dimension_t packet_dimension; 108 108 /** Actual device hardware address. 109 109 */ 110 measured_string_ref addr;110 measured_string_ref addr; 111 111 /** Actual device hardware address data. 112 112 */ 113 char * addr_data;113 char * addr_data; 114 114 /** Broadcast device hardware address. 115 115 */ 116 measured_string_ref broadcast_addr;116 measured_string_ref broadcast_addr; 117 117 /** Broadcast device hardware address data. 118 118 */ 119 char * broadcast_data;119 char * broadcast_data; 120 120 /** Device module service. 121 121 */ 122 services_t service;122 services_t service; 123 123 /** Device module phone. 124 124 */ 125 int phone;125 int phone; 126 126 /** Protocol map. 127 127 * Address map for each protocol. 128 128 */ 129 arp_protos_t protos;129 arp_protos_t protos; 130 130 }; 131 131 … … 135 135 /** Protocol service. 136 136 */ 137 services_t service;137 services_t service; 138 138 /** Actual device protocol address. 139 139 */ 140 measured_string_ref addr;140 measured_string_ref addr; 141 141 /** Actual device protocol address data. 142 142 */ 143 char * addr_data;143 char * addr_data; 144 144 /** Address map. 145 145 */ 146 arp_addr_t addresses;146 arp_addr_t addresses; 147 147 }; 148 148 … … 152 152 /** Networking module phone. 153 153 */ 154 int net_phone;154 int net_phone; 155 155 /** Safety lock. 156 156 */ 157 fibril_rwlock_t lock;157 fibril_rwlock_t lock; 158 158 /** ARP address cache. 159 159 */ 160 arp_cache_t cache;160 arp_cache_t cache; 161 161 /** The client connection processing function. 162 162 * The module skeleton propagates its own one. -
uspace/srv/net/il/arp/arp_header.h
raa85487 raadf01e 57 57 * @see hardware.h 58 58 */ 59 uint16_t hardware;59 uint16_t hardware; 60 60 /** Protocol identifier. 61 61 */ 62 uint16_t protocol;62 uint16_t protocol; 63 63 /** Hardware address length in bytes. 64 64 */ 65 uint8_t hardware_length;65 uint8_t hardware_length; 66 66 /** Protocol address length in bytes. 67 67 */ 68 uint8_t protocol_length;68 uint8_t protocol_length; 69 69 /** ARP packet type. 70 70 * @see arp_oc.h 71 71 */ 72 uint16_t operation;72 uint16_t operation; 73 73 } __attribute__ ((packed)); 74 74 -
uspace/srv/net/il/arp/arp_messages.h
raa85487 raadf01e 75 75 * @param[in] call The message call structure. 76 76 */ 77 #define ARP_GET_NETIF( call ) ( services_t ) IPC_GET_ARG2( * call)77 #define ARP_GET_NETIF(call) (services_t) IPC_GET_ARG2(*call) 78 78 79 79 /*@}*/ -
uspace/srv/net/il/arp/arp_module.c
raa85487 raadf01e 61 61 * @see NAME 62 62 */ 63 void module_print_name( void);63 void module_print_name(void); 64 64 65 65 /** Starts the ARP module. … … 70 70 * @returns Other error codes as defined for the REGISTER_ME() macro function. 71 71 */ 72 int module_start( async_client_conn_t client_connection);72 int module_start(async_client_conn_t client_connection); 73 73 74 74 /** Processes the ARP message. … … 80 80 * @returns Other error codes as defined for the arp_message() function. 81 81 */ 82 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);82 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 83 83 84 84 /** ARP module global data. … … 86 86 extern arp_globals_t arp_globals; 87 87 88 void module_print_name( void){89 printf( "%s", NAME);88 void module_print_name(void){ 89 printf("%s", NAME); 90 90 } 91 91 92 int module_start( async_client_conn_t client_connection){92 int module_start(async_client_conn_t client_connection){ 93 93 ERROR_DECLARE; 94 94 95 ipcarg_t phonehash;95 ipcarg_t phonehash; 96 96 97 async_set_client_connection( client_connection);98 arp_globals.net_phone = net_connect_module( SERVICE_NETWORKING);99 ERROR_PROPAGATE( pm_init());100 if( ERROR_OCCURRED( arp_initialize( client_connection))101 || ERROR_OCCURRED( REGISTER_ME( SERVICE_ARP, & phonehash))){97 async_set_client_connection(client_connection); 98 arp_globals.net_phone = net_connect_module(SERVICE_NETWORKING); 99 ERROR_PROPAGATE(pm_init()); 100 if(ERROR_OCCURRED(arp_initialize(client_connection)) 101 || ERROR_OCCURRED(REGISTER_ME(SERVICE_ARP, &phonehash))){ 102 102 pm_destroy(); 103 103 return ERROR_CODE; … … 110 110 } 111 111 112 int module_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){113 return arp_message( callid, call, answer, answer_count);112 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 113 return arp_message(callid, call, answer, answer_count); 114 114 } 115 115 -
uspace/srv/net/il/arp/arp_module.h
raa85487 raadf01e 46 46 * @returns ENOMEM if there is not enough memory left. 47 47 */ 48 int arp_initialize( async_client_conn_t client_connection);48 int arp_initialize(async_client_conn_t client_connection); 49 49 50 50 /** Processes the ARP message. … … 58 58 * @see IS_NET_ARP_MESSAGE() 59 59 */ 60 int arp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);60 int arp_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 61 61 62 62 #endif -
uspace/srv/net/il/arp/arp_remote.c
raa85487 raadf01e 52 52 #include "arp_messages.h" 53 53 54 int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){55 aid_t message_id;56 ipcarg_t result;54 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 55 aid_t message_id; 56 ipcarg_t result; 57 57 58 message_id = async_send_3( arp_phone, NET_ARP_DEVICE, ( ipcarg_t ) device_id, protocol, netif, NULL);59 measured_strings_send( arp_phone, address, 1);60 async_wait_for( message_id, & result);61 return ( int) result;58 message_id = async_send_3(arp_phone, NET_ARP_DEVICE, (ipcarg_t) device_id, protocol, netif, NULL); 59 measured_strings_send(arp_phone, address, 1); 60 async_wait_for(message_id, &result); 61 return (int) result; 62 62 } 63 63 64 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){65 return generic_translate_req( arp_phone, NET_ARP_TRANSLATE, device_id, protocol, address, 1, translation, data);64 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){ 65 return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id, protocol, address, 1, translation, data); 66 66 } 67 67 68 int arp_clear_device_req( int arp_phone, device_id_t device_id){69 return ( int ) async_req_1_0( arp_phone, NET_ARP_CLEAR_DEVICE, ( ipcarg_t ) device_id);68 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 69 return (int) async_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE, (ipcarg_t) device_id); 70 70 } 71 71 72 int arp_clear_address_req( int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){73 aid_t message_id;74 ipcarg_t result;72 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){ 73 aid_t message_id; 74 ipcarg_t result; 75 75 76 message_id = async_send_2( arp_phone, NET_ARP_CLEAR_ADDRESS, ( ipcarg_t ) device_id, protocol, NULL);77 measured_strings_send( arp_phone, address, 1);78 async_wait_for( message_id, & result);79 return ( int) result;76 message_id = async_send_2(arp_phone, NET_ARP_CLEAR_ADDRESS, (ipcarg_t) device_id, protocol, NULL); 77 measured_strings_send(arp_phone, address, 1); 78 async_wait_for(message_id, &result); 79 return (int) result; 80 80 } 81 81 82 int arp_clean_cache_req( int arp_phone){83 return ( int ) async_req_0_0( arp_phone, NET_ARP_CLEAN_CACHE);82 int arp_clean_cache_req(int arp_phone){ 83 return (int) async_req_0_0(arp_phone, NET_ARP_CLEAN_CACHE); 84 84 } 85 85 86 int arp_connect_module( services_t service ){ 87 if( service != SERVICE_ARP ) return EINVAL; 88 return connect_to_service( SERVICE_ARP ); 86 int arp_connect_module(services_t service){ 87 if(service != SERVICE_ARP){ 88 return EINVAL; 89 } 90 return connect_to_service(SERVICE_ARP); 89 91 } 90 92 91 task_id_t arp_task_get_id( void){93 task_id_t arp_task_get_id(void){ 92 94 return 0; 93 95 }
Note:
See TracChangeset
for help on using the changeset viewer.
