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 |