Subversion Repositories HelenOS

Rev

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

Rev 4077 Rev 4153
Line 121... Line 121...
121
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address );
121
int eth_addr_message( device_id_t device_id, eth_addr_type_t type, measured_string_ref * address );
122
int eth_register_message( services_t service, int phone );
122
int eth_register_message( services_t service, int phone );
123
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender );
123
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender );
124
int eth_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
124
int eth_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
125
void    eth_receiver( ipc_callid_t iid, ipc_call_t * icall );
125
void    eth_receiver( ipc_callid_t iid, ipc_call_t * icall );
126
eth_proto_ref   eth_proccess_packet( packet_t packet );
126
eth_proto_ref   eth_proccess_packet( int dummy, packet_t packet );
127
int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype );
127
int eth_prepare_packet( int dummy, packet_t packet, uint8_t * src_addr, int ethertype );
128
 
128
 
129
int eth_initialize( void ){
129
int eth_initialize( void ){
130
    ERROR_DECLARE;
130
    ERROR_DECLARE;
131
 
131
 
132
    rwlock_initialize( & eth_globals.devices_lock );
132
    rwlock_initialize( & eth_globals.devices_lock );
Line 171... Line 171...
171
        device = ( eth_device_ref ) malloc( sizeof( eth_device_t ));
171
        device = ( eth_device_ref ) malloc( sizeof( eth_device_t ));
172
        if( ! device ) return ENOMEM;
172
        if( ! device ) return ENOMEM;
173
        device->device_id = device_id;
173
        device->device_id = device_id;
174
        device->service = service;
174
        device->service = service;
175
        device->mtu = mtu;
175
        device->mtu = mtu;
-
 
176
        // TODO get dummy setting
-
 
177
        device->dummy = 0;
176
        // bind the device driver
178
        // bind the device driver
177
        device->phone = bind_service( device->service, device->device_id, SERVICE_ETHERNET, 0, eth_receiver );
179
        device->phone = bind_service( device->service, device->device_id, SERVICE_ETHERNET, 0, eth_receiver );
178
        // get hardware address
180
        // get hardware address
179
        message = async_send_1( device->phone, NET_NETIF_GET_ADDR, device->device_id, & answer );
181
        message = async_send_1( device->phone, NET_NETIF_GET_ADDR, device->device_id, & answer );
180
        if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->addr, & device->addr_data, 1 ))){
182
        if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->addr, & device->addr_data, 1 ))){
Line 202... Line 204...
202
    }
204
    }
203
    rwlock_write_unlock( & eth_globals.devices_lock );
205
    rwlock_write_unlock( & eth_globals.devices_lock );
204
    return EOK;
206
    return EOK;
205
}
207
}
206
 
208
 
207
eth_proto_ref eth_proccess_packet( packet_t packet ){
209
eth_proto_ref eth_proccess_packet( int dummy, packet_t packet ){
208
    ERROR_DECLARE;
210
    ERROR_DECLARE;
209
 
211
 
210
    eth_header_ex_ref   header;
212
    eth_header_ex_ref   header;
211
    size_t              length;
213
    size_t              length;
212
    int                 type;
214
    int                 type;
213
    size_t              prefix;
215
    size_t              prefix;
214
    size_t              suffix;
216
    size_t              suffix;
215
    eth_fcs_ref         fcs;
217
    eth_fcs_ref         fcs;
216
 
218
 
217
    length = packet_get_data_length( packet );
219
    length = packet_get_data_length( packet );
-
 
220
    if( dummy ){
-
 
221
        packet_trim( packet, sizeof( eth_preamble_t ), 0 );
-
 
222
    }
218
    if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_SUFFIX ) return NULL;
223
    if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_SUFFIX ) return NULL;
219
    header = ( eth_header_ex_ref ) packet_get_data( packet );
224
    header = ( eth_header_ex_ref ) packet_get_data( packet );
220
    type = ntohs( header->header.ethertype );
225
    type = ntohs( header->header.ethertype );
221
    if( type >= ETH_MIN_PROTO ){
226
    if( type >= ETH_MIN_PROTO ){
222
        // DIX Ethernet
227
        // DIX Ethernet
Line 244... Line 249...
244
        suffix += length - prefix - type;
249
        suffix += length - prefix - type;
245
    }else{
250
    }else{
246
        // invalid length/type, should not occurr
251
        // invalid length/type, should not occurr
247
        return NULL;
252
        return NULL;
248
    }
253
    }
249
    // TODO compute crc with fcs to erase?
254
    if( dummy ){
250
    if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ntohl( * fcs )){
255
        if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ntohl( * fcs )){
251
        return NULL;
256
            return NULL;
-
 
257
        }
252
    }
258
    }
253
    if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR ))
259
    if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR ))
254
    || ERROR_OCCURRED( packet_trim( packet, prefix, suffix ))){
260
    || ERROR_OCCURRED( packet_trim( packet, prefix, suffix ))){
255
        return NULL;
261
        return NULL;
256
    }
262
    }
Line 258... Line 264...
258
}
264
}
259
 
265
 
260
int eth_receive_message( device_id_t device_id, packet_t packet ){
266
int eth_receive_message( device_id_t device_id, packet_t packet ){
261
    eth_proto_ref   proto;
267
    eth_proto_ref   proto;
262
    packet_t        next;
268
    packet_t        next;
-
 
269
    eth_device_ref  device;
-
 
270
    int             dummy;
263
 
271
 
-
 
272
    rwlock_read_lock( & eth_globals.devices_lock );
-
 
273
    device = eth_devices_find( & eth_globals.devices, device_id );
-
 
274
    if( ! device ){
-
 
275
        rwlock_read_unlock( & eth_globals.devices_lock );
-
 
276
        return ENOENT;
-
 
277
    }
-
 
278
    dummy = device->dummy;
-
 
279
    rwlock_read_unlock( & eth_globals.devices_lock );
264
    rwlock_read_lock( & eth_globals.protos_lock );
280
    rwlock_read_lock( & eth_globals.protos_lock );
265
    do{
281
    do{
266
        next = pq_detach( packet );
282
        next = pq_detach( packet );
267
        proto = eth_proccess_packet( packet );
283
        proto = eth_proccess_packet( dummy, packet );
268
        if( proto ){
284
        if( proto ){
269
            async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet ));
285
            async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet ));
270
        }else{
286
        }else{
271
            // drop invalid/unknown
287
            // drop invalid/unknown
272
            packet_release( eth_globals.networking_phone, packet_get_id( packet ));
288
            packet_release( eth_globals.networking_phone, packet_get_id( packet ));
Line 345... Line 361...
345
    }
361
    }
346
    rwlock_write_unlock( & eth_globals.protos_lock );
362
    rwlock_write_unlock( & eth_globals.protos_lock );
347
    return EOK;
363
    return EOK;
348
}
364
}
349
 
365
 
350
int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype ){
366
int eth_prepare_packet( int dummy, packet_t packet, uint8_t * src_addr, int ethertype ){
351
    eth_header_ex_ref   header;
367
    eth_header_ex_ref   header;
352
    eth_fcs_ref         fcs;
368
    eth_fcs_ref         fcs;
353
    uint8_t *           src;
369
    uint8_t *           src;
354
    uint8_t *           dest;
370
    uint8_t *           dest;
355
    int                 length;
371
    int                 length;
356
    int                 i;
372
    int                 i;
357
    void *              padding;
373
    void *              padding;
-
 
374
    eth_preamble_ref    preamble;
358
 
375
 
-
 
376
    if( dummy ){
-
 
377
        preamble = PACKET_PREFIX( packet, eth_preamble_t );
-
 
378
        if( ! preamble ) return ENOMEM;
-
 
379
        for( i = 0; i < 7; ++ i ) preamble->preamble[ i ] = ETH_PREAMBLE;
-
 
380
        preamble->sfd = ETH_SFD;
-
 
381
    }
359
    header = PACKET_PREFIX( packet, eth_header_ex_t );
382
    header = PACKET_PREFIX( packet, eth_header_ex_t );
360
    if( ! header ) return ENOMEM;
383
    if( ! header ) return ENOMEM;
361
    for( i = 0; i < 7; ++ i ) header->header.preamble[ i ] = ETH_PREAMBLE;
-
 
362
    header->header.sfd = ETH_SFD;
-
 
363
    length = packet_get_addr( packet, & src, & dest );
384
    length = packet_get_addr( packet, & src, & dest );
364
    if( length < 0 ) return length;
385
    if( length < 0 ) return length;
365
    if( length < ETH_ADDR ) return EINVAL;
386
    if( length < ETH_ADDR ) return EINVAL;
366
    memcpy( header->header.src, src_addr, ETH_ADDR );
387
    memcpy( header->header.src, src_addr, ETH_ADDR );
367
    memcpy( & header->header.dest, dest, ETH_ADDR );
388
    memcpy( & header->header.dest, dest, ETH_ADDR );
Line 376... Line 397...
376
    header->lsap.dsap = 0xAA;
397
    header->lsap.dsap = 0xAA;
377
    header->lsap.ssap = header->lsap.dsap;
398
    header->lsap.ssap = header->lsap.dsap;
378
    header->lsap.ctrl = 0;
399
    header->lsap.ctrl = 0;
379
    for( i = 0; i < 3; ++ i ) header->snap.proto[ i ] = 0;
400
    for( i = 0; i < 3; ++ i ) header->snap.proto[ i ] = 0;
380
    header->snap.ethertype = ethertype;
401
    header->snap.ethertype = ethertype;
-
 
402
    if( dummy ){
381
    fcs = PACKET_SUFFIX( packet, eth_fcs_t );
403
        fcs = PACKET_SUFFIX( packet, eth_fcs_t );
382
    if( ! fcs ) return ENOMEM;
404
        if( ! fcs ) return ENOMEM;
383
    * fcs = htonl( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 ));
405
        * fcs = htonl( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 ));
-
 
406
    }
384
    return EOK;
407
    return EOK;
385
}
408
}
386
 
409
 
387
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){
410
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){
388
    ERROR_DECLARE;
411
    ERROR_DECLARE;
Line 404... Line 427...
404
        return ENOENT;
427
        return ENOENT;
405
    }
428
    }
406
    // proccess packet queue
429
    // proccess packet queue
407
    next = packet;
430
    next = packet;
408
    do{
431
    do{
409
        if( ERROR_OCCURRED( eth_prepare_packet( next, ( uint8_t * ) device->addr->value, ethertype ))){
432
        if( ERROR_OCCURRED( eth_prepare_packet( device->dummy, next, ( uint8_t * ) device->addr->value, ethertype ))){
410
            // release invalid packet
433
            // release invalid packet
411
            tmp = pq_detach( next );
434
            tmp = pq_detach( next );
412
            packet_release( eth_globals.networking_phone, packet_get_id( next ));
435
            packet_release( eth_globals.networking_phone, packet_get_id( next ));
413
            next = tmp;
436
            next = tmp;
414
        }else{
437
        }else{