Rev 4350 | Rev 4500 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4350 | Rev 4351 | ||
|---|---|---|---|
| Line 254... | Line 254... | ||
| 254 | * @returns EOK on success. |
254 | * @returns EOK on success. |
| 255 | * @returns EINVAL if the packet addresses length is not long enough. |
255 | * @returns EINVAL if the packet addresses length is not long enough. |
| 256 | * @returns EINVAL if the packet is bigger than the device MTU. |
256 | * @returns EINVAL if the packet is bigger than the device MTU. |
| 257 | * @returns ENOMEM if there is not enough memory in the packet. |
257 | * @returns ENOMEM if there is not enough memory in the packet. |
| 258 | */ |
258 | */ |
| 259 | int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype ); |
259 | int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu ); |
| 260 | 260 | ||
| 261 | DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) |
261 | DEVICE_MAP_IMPLEMENT( eth_devices, eth_device_t ) |
| 262 | 262 | ||
| 263 | INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) |
263 | INT_MAP_IMPLEMENT( eth_protos, eth_proto_t ) |
| 264 | 264 | ||
| Line 268... | Line 268... | ||
| 268 | 268 | ||
| 269 | //TODO clear device if off? |
269 | //TODO clear device if off? |
| 270 | rwlock_read_lock( & eth_globals.protos_lock ); |
270 | rwlock_read_lock( & eth_globals.protos_lock ); |
| 271 | for( index = eth_protos_count( & eth_globals.protos ) - 1; index >= 0; -- index ){ |
271 | for( index = eth_protos_count( & eth_globals.protos ) - 1; index >= 0; -- index ){ |
| 272 | proto = eth_protos_get_index( & eth_globals.protos, index ); |
272 | proto = eth_protos_get_index( & eth_globals.protos, index ); |
| 273 | if( proto && proto->phone ) il_device_state_msg( proto->phone, device_id, state ); |
273 | if( proto && proto->phone ) il_device_state_msg( proto->phone, device_id, state, proto->service ); |
| 274 | } |
274 | } |
| 275 | rwlock_read_unlock( & eth_globals.protos_lock ); |
275 | rwlock_read_unlock( & eth_globals.protos_lock ); |
| 276 | return EOK; |
276 | return EOK; |
| 277 | } |
277 | } |
| 278 | 278 | ||
| Line 533... | Line 533... | ||
| 533 | printf( "New protocol registered:\n\tprotocol\t= 0x%x\n\tservice\t= %d\n\tphone\t= %d\n", proto->protocol, proto->service, proto->phone ); |
533 | printf( "New protocol registered:\n\tprotocol\t= 0x%x\n\tservice\t= %d\n\tphone\t= %d\n", proto->protocol, proto->service, proto->phone ); |
| 534 | rwlock_write_unlock( & eth_globals.protos_lock ); |
534 | rwlock_write_unlock( & eth_globals.protos_lock ); |
| 535 | return EOK; |
535 | return EOK; |
| 536 | } |
536 | } |
| 537 | 537 | ||
| 538 | int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype ){ |
538 | int eth_prepare_packet( int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu ){ |
| 539 | eth_header_ex_ref header; |
539 | eth_header_ex_ref header; |
| 540 | eth_header_ref header_dix; |
540 | eth_header_ref header_dix; |
| 541 | eth_fcs_ref fcs; |
541 | eth_fcs_ref fcs; |
| 542 | uint8_t * src; |
542 | uint8_t * src; |
| 543 | uint8_t * dest; |
543 | uint8_t * dest; |
| Line 548... | Line 548... | ||
| 548 | 548 | ||
| 549 | length = packet_get_addr( packet, & src, & dest ); |
549 | length = packet_get_addr( packet, & src, & dest ); |
| 550 | if( length < 0 ) return length; |
550 | if( length < 0 ) return length; |
| 551 | if( length < ETH_ADDR ) return EINVAL; |
551 | if( length < ETH_ADDR ) return EINVAL; |
| 552 | length = packet_get_data_length( packet ); |
552 | length = packet_get_data_length( packet ); |
| 553 | //TODO smaller than MTU! |
- | |
| 554 | if( length > ETH_MAX_TAGGED_CONTENT( flags )) return EINVAL; |
553 | if( length > mtu ) return EINVAL; |
| 555 | if( length < ETH_MIN_TAGGED_CONTENT( flags )){ |
554 | if( length < ETH_MIN_TAGGED_CONTENT( flags )){ |
| 556 | padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
555 | padding = packet_suffix( packet, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
| 557 | if( ! padding ) return ENOMEM; |
556 | if( ! padding ) return ENOMEM; |
| 558 | bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
557 | bzero( padding, ETH_MIN_TAGGED_CONTENT( flags ) - length ); |
| 559 | } |
558 | } |
| Line 611... | Line 610... | ||
| 611 | return ENOENT; |
610 | return ENOENT; |
| 612 | } |
611 | } |
| 613 | // process packet queue |
612 | // process packet queue |
| 614 | next = packet; |
613 | next = packet; |
| 615 | do{ |
614 | do{ |
| 616 | if( ERROR_OCCURRED( eth_prepare_packet( device->flags, next, ( uint8_t * ) device->addr->value, ethertype ))){ |
615 | if( ERROR_OCCURRED( eth_prepare_packet( device->flags, next, ( uint8_t * ) device->addr->value, ethertype, device->mtu ))){ |
| 617 | // release invalid packet |
616 | // release invalid packet |
| 618 | tmp = pq_detach( next ); |
617 | tmp = pq_detach( next ); |
| 619 | pq_release( eth_globals.net_phone, packet_get_id( next )); |
618 | pq_release( eth_globals.net_phone, packet_get_id( next )); |
| 620 | next = tmp; |
619 | next = tmp; |
| 621 | }else{ |
620 | }else{ |