Subversion Repositories HelenOS

Rev

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

Rev 4505 Rev 4558
Line 78... Line 78...
78
 */
78
 */
79
#define ETH_MAX_CONTENT 1500
79
#define ETH_MAX_CONTENT 1500
80
 
80
 
81
/** Minimum packet content length.
81
/** Minimum packet content length.
82
 */
82
 */
83
#define ETH_MIN_CONTENT 46
83
#define ETH_MIN_CONTENT 46u
84
 
84
 
85
/** Maximum tagged packet content length.
85
/** Maximum tagged packet content length.
86
 */
86
 */
87
#define ETH_MAX_TAGGED_CONTENT( flags ) ( ETH_MAX_CONTENT - (( IS_8023_2_LSAP( flags ) || IS_8023_2_SNAP( flags )) ? sizeof( eth_header_lsap_t ) : 0 ) - ( IS_8023_2_SNAP( flags ) ? sizeof( eth_header_snap_t ) : 0 ))
87
#define ETH_MAX_TAGGED_CONTENT( flags ) ( ETH_MAX_CONTENT - (( IS_8023_2_LSAP( flags ) || IS_8023_2_SNAP( flags )) ? sizeof( eth_header_lsap_t ) : 0 ) - ( IS_8023_2_SNAP( flags ) ? sizeof( eth_header_snap_t ) : 0 ))
88
 
88
 
Line 379... Line 379...
379
eth_proto_ref eth_process_packet( int flags, packet_t packet ){
379
eth_proto_ref eth_process_packet( int flags, packet_t packet ){
380
    ERROR_DECLARE;
380
    ERROR_DECLARE;
381
 
381
 
382
    eth_header_ex_ref   header;
382
    eth_header_ex_ref   header;
383
    size_t              length;
383
    size_t              length;
384
    int                 type;
384
    eth_type_t          type;
385
    size_t              prefix;
385
    size_t              prefix;
386
    size_t              suffix;
386
    size_t              suffix;
387
    eth_fcs_ref         fcs;
387
    eth_fcs_ref         fcs;
-
 
388
    uint8_t *           data;
388
 
389
 
389
    length = packet_get_data_length( packet );
390
    length = packet_get_data_length( packet );
390
    if( IS_DUMMY( flags )){
391
    if( IS_DUMMY( flags )){
391
        packet_trim( packet, sizeof( eth_preamble_t ), 0 );
392
        packet_trim( packet, sizeof( eth_preamble_t ), 0 );
392
    }
393
    }
393
    if( length < sizeof( eth_header_t ) + ETH_MIN_CONTENT + ( IS_DUMMY( flags ) ? ETH_SUFFIX : 0 )) return NULL;
394
    if( length < sizeof( eth_header_t ) + ETH_MIN_CONTENT + ( IS_DUMMY( flags ) ? ETH_SUFFIX : 0 )) return NULL;
-
 
395
    data = packet_get_data( packet );
394
    header = ( eth_header_ex_ref ) packet_get_data( packet );
396
    header = ( eth_header_ex_ref ) data;
395
    type = ntohs( header->header.ethertype );
397
    type = ntohs( header->header.ethertype );
396
    if( type >= ETH_MIN_PROTO ){
398
    if( type >= ETH_MIN_PROTO ){
397
        // DIX Ethernet
399
        // DIX Ethernet
398
        prefix = sizeof( eth_header_t );
400
        prefix = sizeof( eth_header_t );
399
        suffix = 0;
401
        suffix = 0;
400
        fcs = (( void * ) header ) + length - sizeof( eth_fcs_t );
402
        fcs = ( eth_fcs_ref ) data + length - sizeof( eth_fcs_t );
-
 
403
        length -= sizeof( eth_fcs_t );
401
    }else if( type <= ETH_MAX_CONTENT ){
404
    }else if( type <= ETH_MAX_CONTENT ){
402
        // translate "LSAP" values
405
        // translate "LSAP" values
403
        if(( header->lsap.dsap == ETH_LSAP_GLSAP ) && ( header->lsap.ssap == ETH_LSAP_GLSAP )){
406
        if(( header->lsap.dsap == ETH_LSAP_GLSAP ) && ( header->lsap.ssap == ETH_LSAP_GLSAP )){
404
            // raw packet
407
            // raw packet
405
            // discard
408
            // discard
Line 412... Line 415...
412
        }else{
415
        }else{
413
            // IEEE 802.3 + 802.2 LSAP
416
            // IEEE 802.3 + 802.2 LSAP
414
            type = lsap_map( header->lsap.dsap );
417
            type = lsap_map( header->lsap.dsap );
415
            prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t);
418
            prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t);
416
        }
419
        }
417
        suffix = ( type < ETH_MIN_CONTENT ) ? ETH_MIN_CONTENT - type : 0;
420
        suffix = ( type < ETH_MIN_CONTENT ) ? ETH_MIN_CONTENT - type : 0u;
418
        fcs = (( void * ) header ) + prefix + type + suffix;
421
        fcs = ( eth_fcs_ref ) data + prefix + type + suffix;
419
        suffix += length - prefix - type;
422
        suffix += length - prefix - type;
-
 
423
        length = prefix + type + suffix;
420
    }else{
424
    }else{
421
        // invalid length/type, should not occurr
425
        // invalid length/type, should not occurr
422
        return NULL;
426
        return NULL;
423
    }
427
    }
424
    if( IS_DUMMY( flags )){
428
    if( IS_DUMMY( flags )){
425
        if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ntohl( * fcs )){
429
        if(( ~ compute_crc32( ~ 0u, data, length * 8 )) != ntohl( * fcs )){
426
            return NULL;
430
            return NULL;
427
        }
431
        }
428
        suffix += sizeof( eth_fcs_t );
432
        suffix += sizeof( eth_fcs_t );
429
    }
433
    }
430
    if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR ))
434
    if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR ))
Line 539... Line 543...
539
    eth_header_ex_ref   header;
543
    eth_header_ex_ref   header;
540
    eth_header_ref      header_dix;
544
    eth_header_ref      header_dix;
541
    eth_fcs_ref         fcs;
545
    eth_fcs_ref         fcs;
542
    uint8_t *           src;
546
    uint8_t *           src;
543
    uint8_t *           dest;
547
    uint8_t *           dest;
544
    int                 length;
548
    size_t              length;
545
    int                 i;
549
    int                 i;
546
    void *              padding;
550
    void *              padding;
547
    eth_preamble_ref    preamble;
551
    eth_preamble_ref    preamble;
548
 
552
 
549
    length = packet_get_addr( packet, & src, & dest );
553
    i = packet_get_addr( packet, & src, & dest );
550
    if( length < 0 ) return length;
554
    if( i < 0 ) return i;
551
    if( length != ETH_ADDR ) return EINVAL;
555
    if( i != ETH_ADDR ) return EINVAL;
552
    length = packet_get_data_length( packet );
556
    length = packet_get_data_length( packet );
553
    if( length > mtu ) return EINVAL;
557
    if( length > mtu ) return EINVAL;
554
    if( length < ETH_MIN_TAGGED_CONTENT( flags )){
558
    if( length < ETH_MIN_TAGGED_CONTENT( flags )){
555
        padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length );
559
        padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length );
556
        if( ! padding ) return ENOMEM;
560
        if( ! padding ) return ENOMEM;
Line 584... Line 588...
584
        src = & header->header.dest[ 0 ];
588
        src = & header->header.dest[ 0 ];
585
    }
589
    }
586
    if( IS_DUMMY( flags )){
590
    if( IS_DUMMY( flags )){
587
        fcs = PACKET_SUFFIX( packet, eth_fcs_t );
591
        fcs = PACKET_SUFFIX( packet, eth_fcs_t );
588
        if( ! fcs ) return ENOMEM;
592
        if( ! fcs ) return ENOMEM;
589
        * fcs = htonl( ~ compute_crc32( ~ 0, src, ((( void * ) fcs ) - (( void * ) src )) * 8 ));
593
        * fcs = htonl( ~ compute_crc32( ~ 0u, src, length * 8 ));
590
    }
594
    }
591
    return EOK;
595
    return EOK;
592
}
596
}
593
 
597
 
594
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){
598
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){
Line 677... Line 681...
677
                break;
681
                break;
678
            case NET_NIL_RECEIVED:
682
            case NET_NIL_RECEIVED:
679
                if( ! ERROR_OCCURRED( packet_translate( eth_globals.net_phone, & packet, IPC_GET_PACKET( icall )))){
683
                if( ! ERROR_OCCURRED( packet_translate( eth_globals.net_phone, & packet, IPC_GET_PACKET( icall )))){
680
                    ERROR_CODE = nil_received_msg( 0, IPC_GET_DEVICE( icall ), packet, 0 );
684
                    ERROR_CODE = nil_received_msg( 0, IPC_GET_DEVICE( icall ), packet, 0 );
681
                }
685
                }
682
                ipc_answer_0( iid, ERROR_CODE );
686
                ipc_answer_0( iid, ( ipcarg_t ) ERROR_CODE );
683
                break;
687
                break;
684
            default:
688
            default:
685
                ipc_answer_0( iid, ENOTSUP );
689
                ipc_answer_0( iid, ( ipcarg_t ) ENOTSUP );
686
        }
690
        }
687
        iid = async_get_call( icall );
691
        iid = async_get_call( icall );
688
    }
692
    }
689
}
693
}
690
 
694