Subversion Repositories HelenOS

Rev

Rev 4558 | Rev 4695 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4558 Rev 4582
Line 36... Line 36...
36
 */
36
 */
37
 
37
 
38
#include <async.h>
38
#include <async.h>
39
#include <malloc.h>
39
#include <malloc.h>
40
#include <mem.h>
40
#include <mem.h>
41
#include <rwlock.h>
41
#include <fibril_sync.h>
42
#include <stdio.h>
42
#include <stdio.h>
43
#include <string.h>
43
#include <string.h>
44
#include <task.h>
44
#include <task.h>
45
 
45
 
46
#include <ipc/ipc.h>
46
#include <ipc/ipc.h>
Line 138... Line 138...
138
}
138
}
139
 
139
 
140
int arp_clear_device_req( int arp_phone, device_id_t device_id ){
140
int arp_clear_device_req( int arp_phone, device_id_t device_id ){
141
    arp_device_ref  device;
141
    arp_device_ref  device;
142
 
142
 
143
    rwlock_write_lock( & arp_globals.lock );
143
    fibril_rwlock_write_lock( & arp_globals.lock );
144
    device = arp_cache_find( & arp_globals.cache, device_id );
144
    device = arp_cache_find( & arp_globals.cache, device_id );
145
    if( ! device ){
145
    if( ! device ){
146
        rwlock_write_unlock( & arp_globals.lock );
146
        fibril_rwlock_write_unlock( & arp_globals.lock );
147
        return ENOENT;
147
        return ENOENT;
148
    }
148
    }
149
    clear_device( device );
149
    clear_device( device );
150
    printf( "Device %d cleared\n", device_id );
150
    printf( "Device %d cleared\n", device_id );
151
    rwlock_write_unlock( & arp_globals.lock );
151
    fibril_rwlock_write_unlock( & arp_globals.lock );
152
    return EOK;
152
    return EOK;
153
}
153
}
154
 
154
 
155
int arp_clean_cache_req( int arp_phone ){
155
int arp_clean_cache_req( int arp_phone ){
156
    int             count;
156
    int             count;
157
    arp_device_ref  device;
157
    arp_device_ref  device;
158
 
158
 
159
    rwlock_write_lock( & arp_globals.lock );
159
    fibril_rwlock_write_lock( & arp_globals.lock );
160
    for( count = arp_cache_count( & arp_globals.cache ) - 1; count >= 0; -- count ){
160
    for( count = arp_cache_count( & arp_globals.cache ) - 1; count >= 0; -- count ){
161
        device = arp_cache_get_index( & arp_globals.cache, count );
161
        device = arp_cache_get_index( & arp_globals.cache, count );
162
        if( device ){
162
        if( device ){
163
            clear_device( device );
163
            clear_device( device );
164
            if( device->addr_data ) free( device->addr_data );
164
            if( device->addr_data ) free( device->addr_data );
165
            if( device->broadcast_data ) free( device->broadcast_data );
165
            if( device->broadcast_data ) free( device->broadcast_data );
166
        }
166
        }
167
    }
167
    }
168
    arp_cache_clear( & arp_globals.cache );
168
    arp_cache_clear( & arp_globals.cache );
169
    rwlock_write_unlock( & arp_globals.lock );
169
    fibril_rwlock_write_unlock( & arp_globals.lock );
170
    printf( "Cache cleaned\n" );
170
    printf( "Cache cleaned\n" );
171
    return EOK;
171
    return EOK;
172
}
172
}
173
 
173
 
174
int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address ){
174
int arp_device_req( int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address ){
Line 185... Line 185...
185
}
185
}
186
 
186
 
187
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 ){
187
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 ){
188
    measured_string_ref tmp;
188
    measured_string_ref tmp;
189
 
189
 
190
    rwlock_read_lock( & arp_globals.lock );
190
    fibril_rwlock_read_lock( & arp_globals.lock );
191
    tmp = arp_translate_message( device_id, protocol, address );
191
    tmp = arp_translate_message( device_id, protocol, address );
192
    if( tmp ){
192
    if( tmp ){
193
        * translation = measured_string_copy( tmp );
193
        * translation = measured_string_copy( tmp );
194
        rwlock_read_unlock( & arp_globals.lock );
194
        fibril_rwlock_read_unlock( & arp_globals.lock );
195
        if( * translation ){
195
        if( * translation ){
196
            * data = ( ** translation ).value;
196
            * data = ( ** translation ).value;
197
            return EOK;
197
            return EOK;
198
        }else{
198
        }else{
199
            return ENOMEM;
199
            return ENOMEM;
200
        }
200
        }
201
    }else{
201
    }else{
202
        rwlock_read_unlock( & arp_globals.lock );
202
        fibril_rwlock_read_unlock( & arp_globals.lock );
203
        return ENOENT;
203
        return ENOENT;
204
    }
204
    }
205
}
205
}
206
 
206
 
207
int arp_initialize( async_client_conn_t client_connection ){
207
int arp_initialize( async_client_conn_t client_connection ){
208
    ERROR_DECLARE;
208
    ERROR_DECLARE;
209
 
209
 
210
    rwlock_initialize( & arp_globals.lock );
210
    fibril_rwlock_initialize( & arp_globals.lock );
211
    rwlock_write_lock( & arp_globals.lock );
211
    fibril_rwlock_write_lock( & arp_globals.lock );
212
    arp_globals.client_connection = client_connection;
212
    arp_globals.client_connection = client_connection;
213
    ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache ));
213
    ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache ));
214
    rwlock_write_unlock( & arp_globals.lock );
214
    fibril_rwlock_write_unlock( & arp_globals.lock );
215
    return EOK;
215
    return EOK;
216
}
216
}
217
 
217
 
218
int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){
218
int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){
219
    ERROR_DECLARE;
219
    ERROR_DECLARE;
Line 236... Line 236...
236
    arp_device_ref  device;
236
    arp_device_ref  device;
237
    arp_proto_ref   proto;
237
    arp_proto_ref   proto;
238
    int             index;
238
    int             index;
239
    hw_type_t       hardware;
239
    hw_type_t       hardware;
240
 
240
 
241
    rwlock_write_lock( & arp_globals.lock );
241
    fibril_rwlock_write_lock( & arp_globals.lock );
242
    // an existing device?
242
    // an existing device?
243
    device = arp_cache_find( & arp_globals.cache, device_id );
243
    device = arp_cache_find( & arp_globals.cache, device_id );
244
    if( device ){
244
    if( device ){
245
        if( device->service != service ){
245
        if( device->service != service ){
246
            printf( "Device %d already exists\n", device->device_id );
246
            printf( "Device %d already exists\n", device->device_id );
247
            rwlock_write_unlock( & arp_globals.lock );
247
            fibril_rwlock_write_unlock( & arp_globals.lock );
248
            return EEXIST;
248
            return EEXIST;
249
        }
249
        }
250
        proto = arp_protos_find( & device->protos, protocol );
250
        proto = arp_protos_find( & device->protos, protocol );
251
        if( proto ){
251
        if( proto ){
252
            free( proto->addr );
252
            free( proto->addr );
253
            free( proto->addr_data );
253
            free( proto->addr_data );
254
            proto->addr = address;
254
            proto->addr = address;
255
            proto->addr_data = address->value;
255
            proto->addr_data = address->value;
256
        }else{
256
        }else{
257
            if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
257
            if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
258
                rwlock_write_unlock( & arp_globals.lock );
258
                fibril_rwlock_write_unlock( & arp_globals.lock );
259
                return ERROR_CODE;
259
                return ERROR_CODE;
260
            }
260
            }
261
            index = arp_protos_add( & device->protos, proto->service, proto );
261
            index = arp_protos_add( & device->protos, proto->service, proto );
262
            if( index < 0 ){
262
            if( index < 0 ){
263
                rwlock_write_unlock( & arp_globals.lock );
263
                fibril_rwlock_write_unlock( & arp_globals.lock );
264
                free( proto );
264
                free( proto );
265
                return index;
265
                return index;
266
            }
266
            }
267
            printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol );
267
            printf( "New protocol added:\n\tdevice id\t= %d\n\tproto\t= %d", device_id, protocol );
268
        }
268
        }
Line 270... Line 270...
270
        hardware = hardware_map( service );
270
        hardware = hardware_map( service );
271
        if( ! hardware ) return ENOENT;
271
        if( ! hardware ) return ENOENT;
272
        // create a new device
272
        // create a new device
273
        device = ( arp_device_ref ) malloc( sizeof( arp_device_t ));
273
        device = ( arp_device_ref ) malloc( sizeof( arp_device_t ));
274
        if( ! device ){
274
        if( ! device ){
275
            rwlock_write_unlock( & arp_globals.lock );
275
            fibril_rwlock_write_unlock( & arp_globals.lock );
276
            return ENOMEM;
276
            return ENOMEM;
277
        }
277
        }
278
        device->hardware = hardware;
278
        device->hardware = hardware;
279
        device->device_id = device_id;
279
        device->device_id = device_id;
280
        if( ERROR_OCCURRED( arp_protos_initialize( & device->protos ))
280
        if( ERROR_OCCURRED( arp_protos_initialize( & device->protos ))
281
        || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
281
        || ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
282
            rwlock_write_unlock( & arp_globals.lock );
282
            fibril_rwlock_write_unlock( & arp_globals.lock );
283
            free( device );
283
            free( device );
284
            return ERROR_CODE;
284
            return ERROR_CODE;
285
        }
285
        }
286
        index = arp_protos_add( & device->protos, proto->service, proto );
286
        index = arp_protos_add( & device->protos, proto->service, proto );
287
        if( index < 0 ){
287
        if( index < 0 ){
288
            rwlock_write_unlock( & arp_globals.lock );
288
            fibril_rwlock_write_unlock( & arp_globals.lock );
289
            arp_protos_destroy( & device->protos );
289
            arp_protos_destroy( & device->protos );
290
            free( device );
290
            free( device );
291
            return index;
291
            return index;
292
        }
292
        }
293
        device->service = service;
293
        device->service = service;
294
        // bind the new one
294
        // bind the new one
295
        device->phone = bind_service( device->service, ( ipcarg_t ) device->device_id, SERVICE_ARP, 0, arp_globals.client_connection );
295
        device->phone = bind_service( device->service, ( ipcarg_t ) device->device_id, SERVICE_ARP, 0, arp_globals.client_connection );
296
        if( device->phone < 0 ){
296
        if( device->phone < 0 ){
297
            rwlock_write_unlock( & arp_globals.lock );
297
            fibril_rwlock_write_unlock( & arp_globals.lock );
298
            arp_protos_destroy( & device->protos );
298
            arp_protos_destroy( & device->protos );
299
            free( device );
299
            free( device );
300
            return EREFUSED;
300
            return EREFUSED;
301
        }
301
        }
302
        // get packet dimensions
302
        // get packet dimensions
303
        if( ERROR_OCCURRED( nil_packet_size_req( device->phone, device_id, & device->addr_len, & device->prefix, & device->content, & device->suffix ))){
303
        if( ERROR_OCCURRED( nil_packet_size_req( device->phone, device_id, & device->addr_len, & device->prefix, & device->content, & device->suffix ))){
304
            rwlock_write_unlock( & arp_globals.lock );
304
            fibril_rwlock_write_unlock( & arp_globals.lock );
305
            arp_protos_destroy( & device->protos );
305
            arp_protos_destroy( & device->protos );
306
            free( device );
306
            free( device );
307
            return ERROR_CODE;
307
            return ERROR_CODE;
308
        }
308
        }
309
        // get hardware address
309
        // get hardware address
310
        if( ERROR_OCCURRED( nil_get_addr( device->phone, device_id, & device->addr, & device->addr_data ))){
310
        if( ERROR_OCCURRED( nil_get_addr( device->phone, device_id, & device->addr, & device->addr_data ))){
311
            rwlock_write_unlock( & arp_globals.lock );
311
            fibril_rwlock_write_unlock( & arp_globals.lock );
312
            arp_protos_destroy( & device->protos );
312
            arp_protos_destroy( & device->protos );
313
            free( device );
313
            free( device );
314
            return ERROR_CODE;
314
            return ERROR_CODE;
315
        }
315
        }
316
        // get broadcast address
316
        // get broadcast address
317
        if( ERROR_OCCURRED( nil_get_broadcast_addr( device->phone, device_id, & device->broadcast_addr, & device->broadcast_data ))){
317
        if( ERROR_OCCURRED( nil_get_broadcast_addr( device->phone, device_id, & device->broadcast_addr, & device->broadcast_data ))){
318
            rwlock_write_unlock( & arp_globals.lock );
318
            fibril_rwlock_write_unlock( & arp_globals.lock );
319
            free( device->addr );
319
            free( device->addr );
320
            free( device->addr_data );
320
            free( device->addr_data );
321
            arp_protos_destroy( & device->protos );
321
            arp_protos_destroy( & device->protos );
322
            free( device );
322
            free( device );
323
            return ERROR_CODE;
323
            return ERROR_CODE;
324
        }
324
        }
325
        if( ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){
325
        if( ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){
326
            rwlock_write_unlock( & arp_globals.lock );
326
            fibril_rwlock_write_unlock( & arp_globals.lock );
327
            free( device->addr );
327
            free( device->addr );
328
            free( device->addr_data );
328
            free( device->addr_data );
329
            free( device->broadcast_addr );
329
            free( device->broadcast_addr );
330
            free( device->broadcast_data );
330
            free( device->broadcast_data );
331
            arp_protos_destroy( & device->protos );
331
            arp_protos_destroy( & device->protos );
332
            free( device );
332
            free( device );
333
            return ERROR_CODE;
333
            return ERROR_CODE;
334
        }
334
        }
335
        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 );
335
        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 );
336
    }
336
    }
337
    rwlock_write_unlock( & arp_globals.lock );
337
    fibril_rwlock_write_unlock( & arp_globals.lock );
338
    return EOK;
338
    return EOK;
339
}
339
}
340
 
340
 
341
measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){
341
measured_string_ref arp_translate_message( device_id_t device_id, services_t protocol, measured_string_ref target ){
342
    arp_device_ref      device;
342
    arp_device_ref      device;
Line 486... Line 486...
486
                free( data );
486
                free( data );
487
            }
487
            }
488
            return ERROR_CODE;
488
            return ERROR_CODE;
489
        case NET_ARP_TRANSLATE:
489
        case NET_ARP_TRANSLATE:
490
            ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1 ));
490
            ERROR_PROPAGATE( measured_strings_receive( & address, & data, 1 ));
491
            rwlock_read_lock( & arp_globals.lock );
491
            fibril_rwlock_read_lock( & arp_globals.lock );
492
            translation = arp_translate_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address );
492
            translation = arp_translate_message( IPC_GET_DEVICE( call ), IPC_GET_SERVICE( call ), address );
493
            free( address );
493
            free( address );
494
            free( data );
494
            free( data );
495
            if( ! translation ){
495
            if( ! translation ){
496
                rwlock_read_unlock( & arp_globals.lock );
496
                fibril_rwlock_read_unlock( & arp_globals.lock );
497
                return ENOENT;
497
                return ENOENT;
498
            }
498
            }
499
            ERROR_CODE = measured_strings_reply( translation, 1 );
499
            ERROR_CODE = measured_strings_reply( translation, 1 );
500
            rwlock_read_unlock( & arp_globals.lock );
500
            fibril_rwlock_read_unlock( & arp_globals.lock );
501
            return ERROR_CODE;
501
            return ERROR_CODE;
502
        case NET_ARP_CLEAR_DEVICE:
502
        case NET_ARP_CLEAR_DEVICE:
503
            return arp_clear_device_req( 0, IPC_GET_DEVICE( call ));
503
            return arp_clear_device_req( 0, IPC_GET_DEVICE( call ));
504
        case NET_ARP_CLEAN_CACHE:
504
        case NET_ARP_CLEAN_CACHE:
505
            return arp_clean_cache_req( 0 );
505
            return arp_clean_cache_req( 0 );
506
        case NET_IL_DEVICE_STATE:
506
        case NET_IL_DEVICE_STATE:
507
            // do nothing - keep the cache
507
            // do nothing - keep the cache
508
            return EOK;
508
            return EOK;
509
        case NET_IL_RECEIVED:
509
        case NET_IL_RECEIVED:
510
            if( ! ERROR_OCCURRED( packet_translate( arp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
510
            if( ! ERROR_OCCURRED( packet_translate( arp_globals.net_phone, & packet, IPC_GET_PACKET( call )))){
511
                rwlock_read_lock( & arp_globals.lock );
511
                fibril_rwlock_read_lock( & arp_globals.lock );
512
                do{
512
                do{
513
                    next = pq_detach( packet );
513
                    next = pq_detach( packet );
514
                    ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( call ), packet );
514
                    ERROR_CODE = arp_receive_message( IPC_GET_DEVICE( call ), packet );
515
                    if( ERROR_CODE != 1 ) pq_release( arp_globals.net_phone, packet_get_id( packet ));
515
                    if( ERROR_CODE != 1 ) pq_release( arp_globals.net_phone, packet_get_id( packet ));
516
                    packet = next;
516
                    packet = next;
517
                }while( packet );
517
                }while( packet );
518
                rwlock_read_unlock( & arp_globals.lock );
518
                fibril_rwlock_read_unlock( & arp_globals.lock );
519
            }
519
            }
520
            return ERROR_CODE;
520
            return ERROR_CODE;
521
    }
521
    }
522
    return ENOTSUP;
522
    return ENOTSUP;
523
}
523
}