Rev 3912 | Rev 4163 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3912 | Rev 3991 | ||
|---|---|---|---|
| Line 33... | Line 33... | ||
| 33 | /** @file |
33 | /** @file |
| 34 | * ARP module implementation. |
34 | * ARP module implementation. |
| 35 | * @see arp.h |
35 | * @see arp.h |
| 36 | */ |
36 | */ |
| 37 | 37 | ||
| 38 | #include <as.h> |
- | |
| 39 | #include <async.h> |
38 | #include <async.h> |
| 40 | #include <malloc.h> |
39 | #include <malloc.h> |
| - | 40 | #include <rwlock.h> |
|
| 41 | #include <stdio.h> |
41 | #include <stdio.h> |
| 42 | #include <string.h> |
42 | #include <string.h> |
| 43 | 43 | ||
| 44 | #include <ipc/ipc.h> |
44 | #include <ipc/ipc.h> |
| 45 | #include <ipc/services.h> |
45 | #include <ipc/services.h> |
| Line 158... | Line 158... | ||
| 158 | INT_MAP_IMPLEMENT( arp_protos, arp_proto_t ) |
158 | INT_MAP_IMPLEMENT( arp_protos, arp_proto_t ) |
| 159 | 159 | ||
| 160 | GENERIC_CHAR_MAP_IMPLEMENT( arp_addr, measured_string_t ) |
160 | GENERIC_CHAR_MAP_IMPLEMENT( arp_addr, measured_string_t ) |
| 161 | 161 | ||
| 162 | int arp_initialize( void ){ |
162 | int arp_initialize( void ){ |
| - | 163 | ERROR_DECLARE; |
|
| - | 164 | ||
| - | 165 | rwlock_initialize( & arp_globals.lock ); |
|
| - | 166 | rwlock_write_lock( & arp_globals.lock ); |
|
| 163 | return arp_cache_initialize( & arp_globals.cache ); |
167 | ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache )); |
| - | 168 | rwlock_write_unlock( & arp_globals.lock ); |
|
| - | 169 | return EOK; |
|
| 164 | } |
170 | } |
| 165 | 171 | ||
| 166 | int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){ |
172 | int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){ |
| 167 | ERROR_DECLARE; |
173 | ERROR_DECLARE; |
| 168 | 174 | ||
| Line 185... | Line 191... | ||
| 185 | aid_t message; |
191 | aid_t message; |
| 186 | ipc_call_t answer; |
192 | ipc_call_t answer; |
| 187 | ipcarg_t result; |
193 | ipcarg_t result; |
| 188 | arp_proto_ref proto; |
194 | arp_proto_ref proto; |
| 189 | 195 | ||
| - | 196 | rwlock_write_lock( & arp_globals.lock ); |
|
| 190 | // an existing device? |
197 | // an existing device? |
| 191 | device = arp_cache_find( & arp_globals.cache, device_id ); |
198 | device = arp_cache_find( & arp_globals.cache, device_id ); |
| 192 | if( device ){ |
199 | if( device ){ |
| 193 | if( device->service != service ) return EEXIST; |
200 | if( device->service != service ){ |
| - | 201 | rwlock_write_unlock( & arp_globals.lock ); |
|
| - | 202 | return EEXIST; |
|
| - | 203 | } |
|
| 194 | proto = arp_protos_find( & device->protos, protocol ); |
204 | proto = arp_protos_find( & device->protos, protocol ); |
| 195 | if( proto ){ |
205 | if( proto ){ |
| 196 | free( proto->addr ); |
206 | free( proto->addr ); |
| 197 | free( proto->addr_data ); |
207 | free( proto->addr_data ); |
| 198 | proto->addr = address; |
208 | proto->addr = address; |
| 199 | proto->addr_data = address->value; |
209 | proto->addr_data = address->value; |
| 200 | }else{ |
210 | }else{ |
| 201 | ERROR_PROPAGATE( arp_proto_create( & proto, protocol, address )); |
211 | if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){ |
| - | 212 | rwlock_write_unlock( & arp_globals.lock ); |
|
| - | 213 | return ERROR_CODE; |
|
| - | 214 | } |
|
| 202 | if( ERROR_OCCURRED( arp_protos_add( & device->protos, proto->service, proto ))){ |
215 | if( ERROR_OCCURRED( arp_protos_add( & device->protos, proto->service, proto ))){ |
| - | 216 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 203 | free( proto ); |
217 | free( proto ); |
| 204 | return ERROR_CODE; |
218 | return ERROR_CODE; |
| 205 | } |
219 | } |
| 206 | } |
220 | } |
| 207 | return EOK; |
221 | return EOK; |
| 208 | }else{ |
222 | }else{ |
| 209 | // create a new device |
223 | // create a new device |
| 210 | device = ( arp_device_ref ) malloc( sizeof( arp_device_t )); |
224 | device = ( arp_device_ref ) malloc( sizeof( arp_device_t )); |
| - | 225 | if( ! device ){ |
|
| - | 226 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 211 | if( ! device ) return ENOMEM; |
227 | return ENOMEM; |
| - | 228 | } |
|
| 212 | device->device_id = device_id; |
229 | device->device_id = device_id; |
| 213 | if( ERROR_OCCURRED( arp_protos_initialize( & device->protos )) |
230 | if( ERROR_OCCURRED( arp_protos_initialize( & device->protos )) |
| 214 | || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){ |
231 | || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){ |
| - | 232 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 215 | free( device ); |
233 | free( device ); |
| 216 | return ERROR_CODE; |
234 | return ERROR_CODE; |
| 217 | } |
235 | } |
| 218 | if( ERROR_OCCURRED( arp_protos_add( & device->protos, proto->service, proto ))){ |
236 | if( ERROR_OCCURRED( arp_protos_add( & device->protos, proto->service, proto ))){ |
| - | 237 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 219 | arp_protos_destroy( & device->protos ); |
238 | arp_protos_destroy( & device->protos ); |
| 220 | free( device ); |
239 | free( device ); |
| 221 | return ERROR_CODE; |
240 | return ERROR_CODE; |
| 222 | } |
241 | } |
| 223 | device->service = service; |
242 | device->service = service; |
| 224 | // bind the new one |
243 | // bind the new one |
| 225 | device->phone = bind_service( device->service, device->device_id, SERVICE_ARP, 0, arp_receiver ); |
244 | device->phone = bind_service( device->service, device->device_id, SERVICE_ARP, 0, arp_receiver ); |
| 226 | // get packet dimensions |
245 | // get packet dimensions |
| 227 | if( ERROR_OCCURRED( async_req_1_4( device->phone, NET_NIL_PACKET_SPACE, device_id, & device->addr_len, & device->prefix, & device->content, & device->suffix ))){ |
246 | if( ERROR_OCCURRED( async_req_1_4( device->phone, NET_NIL_PACKET_SPACE, device_id, & device->addr_len, & device->prefix, & device->content, & device->suffix ))){ |
| - | 247 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 228 | arp_protos_destroy( & device->protos ); |
248 | arp_protos_destroy( & device->protos ); |
| 229 | free( device ); |
249 | free( device ); |
| 230 | return ERROR_CODE; |
250 | return ERROR_CODE; |
| 231 | } |
251 | } |
| 232 | // get hardware address |
252 | // get hardware address |
| 233 | message = async_send_1( device->phone, NET_NIL_ADDR, device->device_id, & answer ); |
253 | message = async_send_1( device->phone, NET_NIL_ADDR, device->device_id, & answer ); |
| 234 | if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->addr, & device->addr_data, 1 ))){ |
254 | if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->addr, & device->addr_data, 1 ))){ |
| - | 255 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 235 | arp_protos_destroy( & device->protos ); |
256 | arp_protos_destroy( & device->protos ); |
| 236 | free( device ); |
257 | free( device ); |
| 237 | async_wait_for( message, NULL ); |
258 | async_wait_for( message, NULL ); |
| 238 | return ERROR_CODE; |
259 | return ERROR_CODE; |
| 239 | } |
260 | } |
| 240 | async_wait_for( message, & result ); |
261 | async_wait_for( message, & result ); |
| 241 | if( ERROR_OCCURRED( result )){ |
262 | if( ERROR_OCCURRED( result )){ |
| - | 263 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 242 | free( device->addr ); |
264 | free( device->addr ); |
| 243 | free( device->addr_data ); |
265 | free( device->addr_data ); |
| 244 | arp_protos_destroy( & device->protos ); |
266 | arp_protos_destroy( & device->protos ); |
| 245 | free( device ); |
267 | free( device ); |
| 246 | return ERROR_CODE; |
268 | return ERROR_CODE; |
| 247 | } |
269 | } |
| 248 | // get broadcast address |
270 | // get broadcast address |
| 249 | message = async_send_1( device->phone, NET_NIL_BROADCAST_ADDR, device->device_id, & answer ); |
271 | message = async_send_1( device->phone, NET_NIL_BROADCAST_ADDR, device->device_id, & answer ); |
| 250 | if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->broadcast_addr, & device->broadcast_data, 1 ))){ |
272 | if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->broadcast_addr, & device->broadcast_data, 1 ))){ |
| - | 273 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 251 | free( device->addr ); |
274 | free( device->addr ); |
| 252 | free( device->addr_data ); |
275 | free( device->addr_data ); |
| 253 | arp_protos_destroy( & device->protos ); |
276 | arp_protos_destroy( & device->protos ); |
| 254 | free( device ); |
277 | free( device ); |
| 255 | async_wait_for( message, NULL ); |
278 | async_wait_for( message, NULL ); |
| Line 257... | Line 280... | ||
| 257 | } |
280 | } |
| 258 | async_wait_for( message, & result ); |
281 | async_wait_for( message, & result ); |
| 259 | // add to the cache |
282 | // add to the cache |
| 260 | if( ERROR_OCCURRED( result ) |
283 | if( ERROR_OCCURRED( result ) |
| 261 | || ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){ |
284 | || ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){ |
| - | 285 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 262 | free( device->addr ); |
286 | free( device->addr ); |
| 263 | free( device->addr_data ); |
287 | free( device->addr_data ); |
| 264 | free( device->broadcast_addr ); |
288 | free( device->broadcast_addr ); |
| 265 | free( device->broadcast_data ); |
289 | free( device->broadcast_data ); |
| 266 | arp_protos_destroy( & device->protos ); |
290 | arp_protos_destroy( & device->protos ); |
| 267 | free( device ); |
291 | free( device ); |
| 268 | return ERROR_CODE; |
292 | return ERROR_CODE; |
| 269 | } |
293 | } |
| 270 | } |
294 | } |
| - | 295 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 271 | return EOK; |
296 | return EOK; |
| 272 | } |
297 | } |
| 273 | 298 | ||
| 274 | measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){ |
299 | measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){ |
| 275 | arp_device_ref device; |
300 | arp_device_ref device; |
| Line 278... | Line 303... | ||
| 278 | size_t length; |
303 | size_t length; |
| 279 | packet_t packet; |
304 | packet_t packet; |
| 280 | arp_header_ref header; |
305 | arp_header_ref header; |
| 281 | 306 | ||
| 282 | if( ! target ) return NULL; |
307 | if( ! target ) return NULL; |
| - | 308 | rwlock_read_lock( & arp_globals.lock ); |
|
| 283 | device = arp_cache_find( & arp_globals.cache, device_id ); |
309 | device = arp_cache_find( & arp_globals.cache, device_id ); |
| 284 | if( ! device ) return NULL; |
310 | if( ! device ){ |
| - | 311 | rwlock_read_unlock( & arp_globals.lock ); |
|
| - | 312 | return NULL; |
|
| - | 313 | } |
|
| 285 | proto = arp_protos_find( & device->protos, protocol ); |
314 | proto = arp_protos_find( & device->protos, protocol ); |
| 286 | if(( ! proto ) || ( proto->addr->length != target->length )) return NULL; |
315 | if(( ! proto ) || ( proto->addr->length != target->length )){ |
| - | 316 | rwlock_read_unlock( & arp_globals.lock ); |
|
| - | 317 | return NULL; |
|
| - | 318 | } |
|
| 287 | addr = arp_addr_find( & proto->addresses, target->value, target->length ); |
319 | addr = arp_addr_find( & proto->addresses, target->value, target->length ); |
| - | 320 | if( addr ){ |
|
| - | 321 | rwlock_read_unlock( & arp_globals.lock ); |
|
| 288 | if( addr ) return addr; |
322 | return addr; |
| - | 323 | } |
|
| 289 | // ARP packet content size = header + ( address + translation ) * 2 |
324 | // ARP packet content size = header + ( address + translation ) * 2 |
| 290 | length = 8 + ( CONVERT_SIZE( char, uint8_t, proto->addr->length ) + CONVERT_SIZE( char, uint8_t, device->addr->length )) * 2; |
325 | length = 8 + ( CONVERT_SIZE( char, uint8_t, proto->addr->length ) + CONVERT_SIZE( char, uint8_t, device->addr->length )) * 2; |
| 291 | if( length > device->content ){ |
326 | if( length > device->content ){ |
| - | 327 | rwlock_read_unlock( & arp_globals.lock ); |
|
| - | 328 | return NULL; |
|
| - | 329 | } |
|
| - | 330 | packet = packet_get_4( arp_globals.networking_phone, device->addr_len, device->prefix, length, device->suffix ); |
|
| - | 331 | if( ! packet ){ |
|
| - | 332 | rwlock_read_unlock( & arp_globals.lock ); |
|
| 292 | return NULL; |
333 | return NULL; |
| 293 | } |
334 | } |
| 294 | packet = packet_get_5( arp_globals.networking_phone, SERVICE_ARP, device->addr_len, device->prefix, length, device->suffix ); |
- | |
| 295 | if( ! packet ) return NULL; |
- | |
| 296 | header = ( arp_header_ref ) packet_suffix( packet, length ); |
335 | header = ( arp_header_ref ) packet_suffix( packet, length ); |
| 297 | header->hardware = device->hardware; |
336 | header->hardware = device->hardware; |
| 298 | header->hardware_length = device->addr->length; |
337 | header->hardware_length = device->addr->length; |
| 299 | header->protocol = protocol_map( device->service, protocol ); |
338 | header->protocol = protocol_map( device->service, protocol ); |
| 300 | header->protocol_length = proto->addr->length; |
339 | header->protocol_length = proto->addr->length; |
| Line 307... | Line 346... | ||
| 307 | memset((( uint8_t * ) header ) + length, 0, device->addr->length ); |
346 | memset((( uint8_t * ) header ) + length, 0, device->addr->length ); |
| 308 | length += device->addr->length; |
347 | length += device->addr->length; |
| 309 | memcpy((( uint8_t * ) header ) + length, target->value, target->length ); |
348 | memcpy((( uint8_t * ) header ) + length, target->value, target->length ); |
| 310 | packet_set_addr( packet, ( uint8_t * ) device->addr->value, ( uint8_t * ) device->broadcast_addr->value, CONVERT_SIZE( char, uint8_t, device->addr->length )); |
349 | packet_set_addr( packet, ( uint8_t * ) device->addr->value, ( uint8_t * ) device->broadcast_addr->value, CONVERT_SIZE( char, uint8_t, device->addr->length )); |
| 311 | async_msg_3( device->phone, NET_NETIF_SEND, device_id, SERVICE_ARP, packet_get_id( packet )); |
350 | async_msg_3( device->phone, NET_NETIF_SEND, device_id, SERVICE_ARP, packet_get_id( packet )); |
| - | 351 | rwlock_read_unlock( & arp_globals.lock ); |
|
| 312 | return NULL; |
352 | return NULL; |
| 313 | } |
353 | } |
| 314 | 354 | ||
| 315 | int arp_receive_message( device_id_t device_id, packet_t packet ){ |
355 | int arp_receive_message( device_id_t device_id, packet_t packet ){ |
| 316 | ERROR_DECLARE; |
356 | ERROR_DECLARE; |
| 317 | 357 | ||
| 318 | size_t length; |
358 | size_t length; |
| 319 | arp_header_ref header; |
359 | arp_header_ref header; |
| 320 | arp_device_ref device; |
360 | arp_device_ref device; |
| 321 | arp_proto_ref proto; |
361 | arp_proto_ref proto; |
| 322 | // arp_addr_ref addr; |
- | |
| 323 | measured_string_ref hw_source; |
362 | measured_string_ref hw_source; |
| 324 | /* measured_string_t proto_target; |
- | |
| 325 | aid_t message; |
- | |
| 326 | ipcarg_t result; |
- | |
| 327 | int index; |
- | |
| 328 | ipc_call_t answer; |
- | |
| 329 | */ uint8_t * src_hw; |
363 | uint8_t * src_hw; |
| 330 | uint8_t * src_proto; |
364 | uint8_t * src_proto; |
| 331 | uint8_t * des_hw; |
365 | uint8_t * des_hw; |
| 332 | uint8_t * des_proto; |
366 | uint8_t * des_proto; |
| 333 | 367 | ||
| 334 | length = packet_get_data_length( packet ); |
368 | length = packet_get_data_length( packet ); |
| 335 | if( length <= sizeof( arp_header_t )) return EINVAL; |
369 | if( length <= sizeof( arp_header_t )) return EINVAL; |
| - | 370 | rwlock_read_lock( & arp_globals.lock ); |
|
| 336 | device = arp_cache_find( & arp_globals.cache, device_id ); |
371 | device = arp_cache_find( & arp_globals.cache, device_id ); |
| - | 372 | if( ! device ){ |
|
| - | 373 | rwlock_read_unlock( & arp_globals.lock ); |
|
| 337 | if( ! device ) return ENOENT; |
374 | return ENOENT; |
| - | 375 | } |
|
| 338 | header = ( arp_header_ref ) packet_get_data( packet ); |
376 | header = ( arp_header_ref ) packet_get_data( packet ); |
| 339 | if( header->hardware != device->hardware ) return EINVAL; |
377 | if(( header->hardware != device->hardware ) |
| 340 | if( length < sizeof( arp_header_t ) + ( header->hardware_length + header->protocol_length ) * 2 ) return EINVAL; |
378 | || ( length < sizeof( arp_header_t ) + ( header->hardware_length + header->protocol_length ) * 2 )){ |
| - | 379 | rwlock_read_unlock( & arp_globals.lock ); |
|
| - | 380 | return EINVAL; |
|
| - | 381 | } |
|
| 341 | proto = arp_protos_find( & device->protos, protocol_unmap( device->service, header->protocol )); |
382 | proto = arp_protos_find( & device->protos, protocol_unmap( device->service, header->protocol )); |
| - | 383 | if( ! proto ){ |
|
| - | 384 | rwlock_read_unlock( & arp_globals.lock ); |
|
| 342 | if( ! proto ) return ENOENT; |
385 | return ENOENT; |
| - | 386 | } |
|
| 343 | src_hw = (( uint8_t * ) header ) + sizeof( arp_header_t ); |
387 | src_hw = (( uint8_t * ) header ) + sizeof( arp_header_t ); |
| 344 | src_proto = src_hw + header->hardware_length; |
388 | src_proto = src_hw + header->hardware_length; |
| 345 | des_hw = src_proto + header->protocol_length; |
389 | des_hw = src_proto + header->protocol_length; |
| 346 | des_proto = des_hw + header->hardware_length; |
390 | des_proto = des_hw + header->hardware_length; |
| 347 | hw_source = arp_addr_find( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length )); |
391 | hw_source = arp_addr_find( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length )); |
| 348 | // exists? |
392 | // exists? |
| 349 | if( hw_source ){ |
393 | if( hw_source ){ |
| 350 | if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )) return EINVAL; |
394 | if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){ |
| - | 395 | rwlock_read_unlock( & arp_globals.lock ); |
|
| - | 396 | return EINVAL; |
|
| - | 397 | } |
|
| 351 | memcpy( hw_source->value, src_hw, hw_source->length ); |
398 | memcpy( hw_source->value, src_hw, hw_source->length ); |
| 352 | } |
399 | } |
| 353 | // is my protocol address? |
400 | // is my protocol address? |
| 354 | // TODO query protocol module? |
- | |
| 355 | /* proto_target.value = des_proto; |
- | |
| 356 | proto_target.length = header->protocol_length; |
401 | if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){ |
| 357 | // TODO send necessary? |
- | |
| 358 | message = async_send_0( proto->phone, NET_IL_MY_ADDR, & answer ); |
- | |
| 359 | if( ERROR_OCCURRED( measured_strings_send( device->phone, & proto_target, 1 ))){ |
- | |
| 360 | async_wait_for( message, NULL ); |
402 | rwlock_read_unlock( & arp_globals.lock ); |
| 361 | return ERROR_CODE; |
403 | return EINVAL; |
| 362 | } |
404 | } |
| 363 | async_wait_for( message, & result ); |
- | |
| 364 | if( result == EOK ){ |
- | |
| 365 | */ if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )) return EINVAL; |
- | |
| 366 | if( ! strncmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){ |
405 | if( ! strncmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){ |
| 367 | // not already upadted? |
406 | // not already upadted? |
| 368 | if( ! hw_source ){ |
407 | if( ! hw_source ){ |
| 369 | hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length )); |
408 | hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length )); |
| 370 | if( ! hw_source ) return ENOMEM; |
409 | if( ! hw_source ){ |
| - | 410 | rwlock_read_unlock( & arp_globals.lock ); |
|
| - | 411 | return ENOMEM; |
|
| - | 412 | } |
|
| 371 | ERROR_PROPAGATE( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source )); |
413 | if( ERROR_OCCURRED( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source ))){ |
| - | 414 | rwlock_read_unlock( & arp_globals.lock ); |
|
| - | 415 | return ERROR_CODE; |
|
| - | 416 | } |
|
| 372 | } |
417 | } |
| 373 | if( header->operation == ARPOP_REQUEST ){ |
418 | if( header->operation == ARPOP_REQUEST ){ |
| 374 | header->operation = ARPOP_REPLY; |
419 | header->operation = ARPOP_REPLY; |
| 375 | /* for( index = 0; index + header->hardware_length < header->protocol_length; index += header->hardware_length ){ |
- | |
| 376 | memcpy( src_hw, src_proto + index, header->hardware_length ); |
- | |
| 377 | memcpy( src_proto + index, des_proto + index, header->hardware_length ); |
- | |
| 378 | memcpy( des_proto + index, src_hw, header->hardware_length ); |
- | |
| 379 | } |
- | |
| 380 | memcpy( src_hw, src_proto + index, header->hardware_length - header->protocol_length ); |
- | |
| 381 | memcpy( src_proto + index, des_proto + index, header->hardware_length - header->protocol_length ); |
- | |
| 382 | memcpy( des_proto + index, src_hw, header->hardware_length - header->protocol_length ); |
- | |
| 383 | memcpy( src_hw, des_hw, header->hardware_length ); |
- | |
| 384 | memcpy( des_hw, hw_source->value, hw_source->length ); |
- | |
| 385 | */ memcpy( des_proto, src_proto, header->protocol_length ); |
420 | memcpy( des_proto, src_proto, header->protocol_length ); |
| 386 | memcpy( src_proto, proto->addr->value, header->protocol_length ); |
421 | memcpy( src_proto, proto->addr->value, header->protocol_length ); |
| 387 | memcpy( src_hw, des_hw, header->hardware_length ); |
422 | memcpy( src_hw, des_hw, header->hardware_length ); |
| 388 | memcpy( des_hw, hw_source->value, header->hardware_length ); |
423 | memcpy( des_hw, hw_source->value, header->hardware_length ); |
| 389 | packet_set_addr( packet, src_hw, des_hw, header->hardware_length ); |
424 | packet_set_addr( packet, src_hw, des_hw, header->hardware_length ); |
| 390 | async_msg_3( device->phone, NET_NETIF_SEND, device_id, SERVICE_ARP, packet_get_id( packet )); |
425 | async_msg_3( device->phone, NET_NETIF_SEND, device_id, SERVICE_ARP, packet_get_id( packet )); |
| - | 426 | rwlock_read_unlock( & arp_globals.lock ); |
|
| 391 | }else{ |
427 | }else{ |
| - | 428 | rwlock_read_unlock( & arp_globals.lock ); |
|
| 392 | packet_release( arp_globals.networking_phone, packet_get_id( packet )); |
429 | packet_release( arp_globals.networking_phone, packet_get_id( packet )); |
| 393 | } |
430 | } |
| 394 | } |
431 | } |
| 395 | return EOK; |
432 | return EOK; |
| 396 | } |
433 | } |
| 397 | 434 | ||
| 398 | int arp_clear_device_message( device_id_t device_id ){ |
435 | int arp_clear_device_message( device_id_t device_id ){ |
| 399 | arp_device_ref device; |
436 | arp_device_ref device; |
| 400 | 437 | ||
| - | 438 | rwlock_write_lock( & arp_globals.lock ); |
|
| 401 | device = arp_cache_find( & arp_globals.cache, device_id ); |
439 | device = arp_cache_find( & arp_globals.cache, device_id ); |
| - | 440 | if( ! device ){ |
|
| - | 441 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 402 | if( ! device ) return ENOENT; |
442 | return ENOENT; |
| - | 443 | } |
|
| 403 | clear_device( device ); |
444 | clear_device( device ); |
| - | 445 | rwlock_write_unlock( & arp_globals.lock ); |
|
| 404 | return EOK; |
446 | return EOK; |
| 405 | } |
447 | } |
| 406 | 448 | ||
| 407 | void clear_device( arp_device_ref device ){ |
449 | void clear_device( arp_device_ref device ){ |
| 408 | int count; |
450 | int count; |
| Line 421... | Line 463... | ||
| 421 | 463 | ||
| 422 | int arp_clean_cache_message( void ){ |
464 | int arp_clean_cache_message( void ){ |
| 423 | int count; |
465 | int count; |
| 424 | arp_device_ref device; |
466 | arp_device_ref device; |
| 425 | 467 | ||
| - | 468 | rwlock_write_lock( & arp_globals.lock ); |
|
| 426 | count = arp_cache_count( & arp_globals.cache ); |
469 | count = arp_cache_count( & arp_globals.cache ); |
| 427 | while( count > 0 ){ |
470 | while( count > 0 ){ |
| 428 | device = arp_cache_get_index( & arp_globals.cache, count ); |
471 | device = arp_cache_get_index( & arp_globals.cache, count ); |
| 429 | if( device ){ |
472 | if( device ){ |
| 430 | clear_device( device ); |
473 | clear_device( device ); |
| 431 | if( device->addr_data ) free( device->addr_data ); |
474 | if( device->addr_data ) free( device->addr_data ); |
| 432 | if( device->broadcast_data ) free( device->broadcast_data ); |
475 | if( device->broadcast_data ) free( device->broadcast_data ); |
| 433 | } |
476 | } |
| 434 | } |
477 | } |
| 435 | arp_cache_clear( & arp_globals.cache ); |
478 | arp_cache_clear( & arp_globals.cache ); |
| - | 479 | rwlock_write_lock( & arp_globals.lock ); |
|
| 436 | return EOK; |
480 | return EOK; |
| 437 | } |
481 | } |
| 438 | 482 | ||
| 439 | int arp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ |
483 | int arp_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){ |
| 440 | ERROR_DECLARE; |
484 | ERROR_DECLARE; |
| Line 475... | Line 519... | ||
| 475 | packet_t packet; |
519 | packet_t packet; |
| 476 | 520 | ||
| 477 | while( true ){ |
521 | while( true ){ |
| 478 | switch( IPC_GET_METHOD( * icall )){ |
522 | switch( IPC_GET_METHOD( * icall )){ |
| 479 | case NET_IL_DEVICE_STATE: |
523 | case NET_IL_DEVICE_STATE: |
| 480 | //TODO clear device if off? |
524 | // do nothing - keep the cache |
| - | 525 | ipc_answer_0( iid, EOK ); |
|
| 481 | break; |
526 | break; |
| 482 | case NET_IL_RECEIVED: |
527 | case NET_IL_RECEIVED: |
| 483 | if( ! ERROR_OCCURRED( packet_translate( arp_globals.networking_phone, & packet, IPC_GET_PACKET( icall )))){ |
528 | if( ! ERROR_OCCURRED( packet_translate( arp_globals.networking_phone, & packet, IPC_GET_PACKET( icall )))){ |
| 484 | ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( icall ), packet ); |
529 | ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( icall ), packet ); |
| 485 | } |
530 | } |