Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4074 → Rev 4075

/branches/network/uspace/srv/net/nil/eth/eth.c
48,6 → 48,8
#include "../../modules.h"
 
#include "../../include/byteorder.h"
#include "../../include/crc.h"
#include "../../include/ethernet_lsap.h"
#include "../../include/ethernet_protocols.h"
#include "../../include/protocol_map.h"
#include "../../netif/device.h"
62,10 → 64,9
#include "eth_module.h"
 
#define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t ))
#define ETH_SUFFIX 4
#define ETH_MAX_CONTENT ( ETH_MIN_PROTO - 1 )
#define ETH_SUFFIX sizeof( eth_fcs_t )
#define ETH_MAX_CONTENT 1500
#define ETH_MIN_CONTENT 46
#define ETH_PADDING ETH_SUFFIX
 
/** Returns the device identifier message parameter.
*/
122,6 → 123,8
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender );
int eth_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
void eth_receiver( ipc_callid_t iid, ipc_call_t * icall );
eth_proto_ref eth_proccess_packet( packet_t packet );
int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype );
 
int eth_initialize( void ){
ERROR_DECLARE;
201,55 → 204,76
return EOK;
}
 
int eth_receive_message( device_id_t device_id, packet_t packet ){
eth_proto_ref eth_proccess_packet( packet_t packet ){
ERROR_DECLARE;
 
eth_header_ex_ref header;
size_t length;
int type;
eth_proto_ref proto;
size_t size;
size_t prefix;
size_t suffix;
eth_fcs_ref fcs;
 
length = packet_get_data_length( packet );
if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_PADDING ) return EINVAL;
// TODO check CRC padding?
if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_SUFFIX ) return NULL;
header = ( eth_header_ex_ref ) packet_get_data( packet );
type = ntohs( header->header.ethertype );
if( type >= ETH_MIN_PROTO ){
// DIX Ethernet
size = sizeof( eth_header_t );
}else{
// TODO check length?
prefix = sizeof( eth_header_t );
suffix = sizeof( eth_fcs_t );
fcs = (( void * ) header ) + length - suffix;
}else if( type <= ETH_MAX_CONTENT ){
// translate "LSAP" values
if(( header->lsap.dsap == ETH_RAW ) && ( header->lsap.ssap == ETH_RAW )){
if(( header->lsap.dsap == ETH_LSAP_GLSAP ) && ( header->lsap.ssap == ETH_LSAP_GLSAP )){
// raw packet
// discard
return EINVAL;
return NULL;
}else if(( header->lsap.dsap == ETH_LSAP_SNAP ) && ( header->lsap.ssap == ETH_LSAP_SNAP )){
// IEEE 802.3 SNAP
// IEEE 802.3 + 802.2 + LSAP + SNAP
// organization code not supported
type = ntohs( header->snap.ethertype );
size = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t) + sizeof( eth_header_snap_t);
prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t) + sizeof( eth_header_snap_t);
}else{
// IEEE 802.3 + 802.2 LSAP
// TODO lsap numbers
type = header->lsap.dsap;
size = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t);
type = lsap_map( header->lsap.dsap );
prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t);
}
suffix = ( type < ETH_MIN_CONTENT ) ? ETH_MIN_CONTENT - type : 0;
fcs = (( void * ) header ) + prefix + type + suffix;
suffix += length - prefix - type;
}else{
// invalid length/type, should not occurr
return NULL;
}
rwlock_write_lock( & eth_globals.protos_lock );
proto = eth_protos_find( & eth_globals.protos, type );
if( ! proto ){
rwlock_write_unlock( & eth_globals.protos_lock );
return ENOENT;
// TODO compute crc with fcs to erase?
if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ( * fcs )){
return NULL;
}
if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR ))
|| ERROR_OCCURRED( packet_trim( packet, size, ETH_PADDING ))){
rwlock_write_unlock( & eth_globals.protos_lock );
return ERROR_CODE;
|| ERROR_OCCURRED( packet_trim( packet, prefix, suffix ))){
return NULL;
}
async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet ));
rwlock_write_unlock( & eth_globals.protos_lock );
return eth_protos_find( & eth_globals.protos, type );
}
 
int eth_receive_message( device_id_t device_id, packet_t packet ){
eth_proto_ref proto;
packet_t next;
 
rwlock_read_lock( & eth_globals.protos_lock );
do{
next = pq_detach( packet );
proto = eth_proccess_packet( packet );
if( proto ){
async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet ));
}else{
// drop invalid/unknown
packet_release( eth_globals.networking_phone, packet_get_id( packet ));
}
packet = next;
}while( packet );
rwlock_read_unlock( & eth_globals.protos_lock );
return EOK;
}
 
267,7 → 291,7
rwlock_write_unlock( & eth_globals.devices_lock );
* addr_len = ETH_ADDR;
* prefix = ETH_PREFIX;
* suffix = ETH_SUFFIX;
* suffix = ETH_MIN_CONTENT + ETH_SUFFIX;
return EOK;
}
 
323,15 → 347,14
return EOK;
}
 
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){
ERROR_DECLARE;
 
eth_device_ref device;
int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype ){
eth_header_ex_ref header;
eth_fcs_ref fcs;
uint8_t * src;
uint8_t * dest;
int length;
int i;
void * padding;
 
header = PACKET_PREFIX( packet, eth_header_ex_t );
if( ! header ) return ENOMEM;
340,12 → 363,14
length = packet_get_addr( packet, & src, & dest );
if( length < 0 ) return length;
if( length < ETH_ADDR ) return EINVAL;
// TODO src set?
// TODO set addresses
memcpy( header->header.src, src_addr, ETH_ADDR );
memcpy( & header->header.dest, dest, ETH_ADDR );
length = packet_get_data_length( packet );
if( length > ETH_MAX_CONTENT ) return EINVAL;
if( length < ETH_MIN_CONTENT ){
// TODO pad zeros
padding = packet_suffix( packet, ETH_MIN_CONTENT - length );
if( ! padding ) return ENOMEM;
memset( padding, 0, ETH_MIN_CONTENT - length );
}
header->header.ethertype = htons( length );
header->lsap.dsap = 0xAA;
352,15 → 377,47
header->lsap.ssap = header->lsap.dsap;
header->lsap.ctrl = 0;
for( i = 0; i < 3; ++ i ) header->snap.proto[ i ] = 0;
header->snap.ethertype = htons( protocol_map( SERVICE_ETHERNET, sender ));
if( ! header ) return ENOENT;
// TODO eth padding
if( ! packet_suffix( packet, ETH_PADDING )){
return ENOMEM;
header->snap.ethertype = ethertype;
fcs = PACKET_SUFFIX( packet, eth_fcs_t );
if( ! fcs ) return ENOMEM;
* fcs = ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 );
return EOK;
}
 
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){
ERROR_DECLARE;
 
eth_device_ref device;
packet_t next;
packet_t tmp;
int ethertype;
 
ethertype = htons( protocol_map( SERVICE_ETHERNET, sender ));
if( ! ethertype ){
packet_release( eth_globals.networking_phone, packet_get_id( packet ));
return EINVAL;
}
rwlock_write_lock( & eth_globals.devices_lock );
rwlock_write_unlock( & eth_globals.devices_lock );
rwlock_read_lock( & eth_globals.devices_lock );
device = eth_devices_find( & eth_globals.devices, device_id );
if( ! device ){
rwlock_read_unlock( & eth_globals.devices_lock );
return ENOENT;
}
// proccess packet queue
next = packet;
do{
if( ERROR_OCCURRED( eth_prepare_packet( next, ( uint8_t * ) device->addr->value, ethertype ))){
// release invalid packet
tmp = pq_detach( next );
packet_release( eth_globals.networking_phone, packet_get_id( next ));
next = tmp;
}else{
next = pq_next( next );
}
}while( next );
// send packet queue
async_msg_2( device->phone, NET_NETIF_SEND, device_id, packet_get_id( packet ));
rwlock_read_unlock( & eth_globals.devices_lock );
return EOK;
}
 
/branches/network/uspace/srv/net/nil/eth/Makefile
37,6 → 37,7
$(NAME).c \
$(NET_BASE)module.c \
$(NET_BASE)modules.c \
$(NET_BASE)crc.c \
$(STRUCTURES)measured_strings.c \
$(STRUCTURES)packet/packet.c \
$(STRUCTURES)packet/packet_client.c
/branches/network/uspace/srv/net/nil/eth/eth_header.h
44,12 → 44,8
 
#define ETH_PREAMBLE 0x55
 
#define ETH_SFD 0xF5
#define ETH_SFD 0xD5
 
#define ETH_LSAP_SNAP 0xAA
 
#define ETH_RAW 0xFF
 
/** Type definition of the Ethernet header with all the extensions.
* @see eth_header_ex
*/
158,6 → 154,14
eth_header_snap_t snap;
};
 
/** Ethernet Frame Check Sequence.
*/
typedef uint32_t eth_fcs_t;
 
/** Ethernet Frame Check Sequence pointer.
*/
typedef eth_fcs_t * eth_fcs_ref;
 
#endif
 
/** @}
/branches/network/uspace/srv/net/include/ethernet_lsap.h
0,0 → 1,125
/*
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup eth
* @{
*/
 
/** @file
* Link service access point identifiers.
*/
 
#ifndef __NET_ETHERNET_LSAP_H__
#define __NET_ETHERNET_LSAP_H__
 
/** Null LSAP LSAP identifier.
*/
#define ETH_LSAP_NULL 0x00
/** Individual LLC Sublayer Management Function LSAP identifier.
*/
#define ETH_LSAP_ISLMF 0x02
/** Group LLC Sublayer Management Function LSAP identifier.
*/
#define ETH_LSAP_GSLMI 0x03
/** IBM SNA Path Control (individual) LSAP identifier.
*/
#define ETH_LSAP_ISNA 0x04
/** IBM SNA Path Control (group) LSAP identifier.
*/
#define ETH_LSAP_GSNA 0x05
/** ARPANET Internet Protocol (IP) LSAP identifier.
*/
#define ETH_LSAP_IP 0x06
/** SNA LSAP identifier.
*/
#define ETH_LSAP_SNA 0x08
/** SNA LSAP identifier.
*/
#define ETH_LSAP_SNA2 0x0C
/** PROWAY (IEC955) Network Management & Initialization LSAP identifier.
*/
#define ETH_LSAP_PROWAY_NMI 0x0E
/** Texas Instruments LSAP identifier.
*/
#define ETH_LSAP_TI 0x18
/** IEEE 802.1 Bridge Spanning Tree Protocol LSAP identifier.
*/
#define ETH_LSAP_BRIDGE 0x42
/** EIA RS-511 Manufacturing Message Service LSAP identifier.
*/
#define ETH_LSAP_EIS 0x4E
/** ISO 8208 (X.25 over IEEE 802.2 Type 2 LLC) LSAP identifier.
*/
#define ETH_LSAP_ISO8208 0x7E
/** Xerox Network Systems (XNS) LSAP identifier.
*/
#define ETH_LSAP_XNS 0x80
/** Nestar LSAP identifier.
*/
#define ETH_LSAP_NESTAR 0x86
/** PROWAY (IEC 955) Active Station List Maintenance LSAP identifier.
*/
#define ETH_LSAP_PROWAY_ASLM 0x8E
/** ARPANET Address Resolution Protocol (ARP) LSAP identifier.
*/
#define ETH_LSAP_ARP 0x98
/** Banyan VINES LSAP identifier.
*/
#define ETH_LSAP_VINES 0xBC
/** SubNetwork Access Protocol (SNAP) LSAP identifier.
*/
#define ETH_LSAP_SNAP 0xAA
/** Novell NetWare LSAP identifier.
*/
#define ETH_LSAP_NETWARE 0xE0
/** IBM NetBIOS LSAP identifier.
*/
#define ETH_LSAP_NETBIOS 0xF0
/** IBM LAN Management (individual) LSAP identifier.
*/
#define ETH_LSAP_ILAN 0xF4
/** IBM LAN Management (group) LSAP identifier.
*/
#define ETH_LSAP_GLAN 0xF5
/** IBM Remote Program Load (RPL) LSAP identifier.
*/
#define ETH_LSAP_RPL 0xF8
/** Ungermann-Bass LSAP identifier.
*/
#define ETH_LSAP_UB 0xFA
/** ISO Network Layer Protocol LSAP identifier.
*/
#define ETH_LSAP_ISONLP 0xFE
/** Global LSAP LSAP identifier.
*/
#define ETH_LSAP_GLSAP 0xFF
 
#endif
 
/** @}
*/
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/branches/network/uspace/srv/net/include/protocol_map.h
39,6 → 39,7
 
#include <ipc/services.h>
 
#include "ethernet_lsap.h"
#include "ethernet_protocols.h"
 
/** Maps the internetwork layer service to the network interface layer type.
85,6 → 86,22
}
}
 
/** Maps the link service access point identifier to the Ethernet protocol identifier.
* @param lsap Link service access point identifier. Input parameter.
* @returns Ethernet protocol identifier of the link service access point identifier.
* @returns ETH_LSAP_NULL if mapping is not found.
*/
static inline int lsap_map( int lsap ){
switch( lsap ){
case ETH_LSAP_IP:
return ETH_P_IP;
case ETH_LSAP_ARP:
return ETH_P_ARP;
default:
return ETH_LSAP_NULL;
}
}
 
#endif
 
/** @}
/branches/network/uspace/srv/net/include/ethernet_protocols.h
39,8 → 39,9
#define __NET_ETHERNET_PROTOCOLS_H__
 
/** Ethernet minimal protocol number.
* According to the IEEE 802.3 specification.
*/
#define ETH_MIN_PROTO 1501
#define ETH_MIN_PROTO 0x0600 /*1536*/
 
/** Ethernet loopback packet protocol type.
*/
/branches/network/uspace/srv/net/include/crc.h
0,0 → 1,75
/*
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
* @{
*/
 
/** @file
* General CRC computation.
*/
 
#ifndef __NET_CRC_H__
#define __NET_CRC_H__
 
#include <byteorder.h>
 
#include <sys/types.h>
 
/** Computes CRC32 value.
* @param seed Initial value. Often used as 0 or ~0. Input parameter.
* @param data Pointer to the beginning of data to process. Input parameter.
* @param length Length of the data in bits. Input parameter.
* @returns The computed CRC32 of the length bits of the data.
*/
#ifdef ARCH_IS_BIG_ENDIAN
#define compute_crc32( seed, data, length ) compute_crc32_be( seed, ( uint8_t * ) data, length )
#else
#define compute_crc32( seed, data, length ) compute_crc32_le( seed, ( uint8_t * ) data, length )
#endif
 
/** Computes CRC32 value in the little-endian environment.
* @param seed Initial value. Often used as 0 or ~0. Input parameter.
* @param data Pointer to the beginning of data to process. Input parameter.
* @param length Length of the data in bits. Input parameter.
* @returns The computed CRC32 of the length bits of the data.
*/
uint32_t compute_crc32_le( uint32_t seed, uint8_t * data, int length );
 
/** Computes CRC32 value in the big-endian environment.
* @param seed Initial value. Often used as 0 or ~0. Input parameter.
* @param data Pointer to the beginning of data to process. Input parameter.
* @param length Length of the data in bits. Input parameter.
* @returns The computed CRC32 of the length bits of the data.
*/
uint32_t compute_crc32_be( uint32_t seed, uint8_t * data, int length );
 
#endif
 
/** @}
*/
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/branches/network/uspace/srv/net/structures/packet/packet.c
250,5 → 250,15
}
}
 
packet_t pq_next( packet_t packet ){
if( ! packet_is_valid( packet )) return NULL;
return pm_find( packet->next );
}
 
packet_t pq_previous( packet_t packet ){
if( ! packet_is_valid( packet )) return NULL;
return pm_find( packet->previous );
}
 
/** @}
*/
/branches/network/uspace/srv/net/structures/packet/packet_client.h
193,9 → 193,10
*/
packet_t packet_get_1( int phone, size_t content );
 
/** Releases the packet.
* The packet is marked as free for use.
* The module should not use the packet after this point until it is received or obtained again.
/** Releases the packet queue.
* All packets in the queue are marked as free for use.
* The packet queue may be one packet only.
* The module should not use the packets after this point until they are received or obtained again.
* @param phone The packet server module phone. Input parameter.
* @param packet_id The packet identifier. Input parameter.
*/
/branches/network/uspace/srv/net/structures/packet/packet.h
129,6 → 129,22
*/
void pq_destroy( packet_t first, void ( * packet_release )( packet_t packet ));
 
/** Returns the next packet in the queue.
* @param packet The packet queue member. Input parameter.
* @returns The next packet in the queue.
* @returns NULL if there is no next packet.
* @returns NULL if the packet is not valid.
*/
packet_t pq_next( packet_t packet );
 
/** Returns the previous packet in the queue.
* @param packet The packet queue member. Input parameter.
* @returns The previous packet in the queue.
* @returns NULL if there is no previous packet.
* @returns NULL if the packet is not valid.
*/
packet_t pq_previous( packet_t packet );
 
#endif
 
/** @}
/branches/network/uspace/srv/net/networking/startup/Makefile
41,7 → 41,9
$(NAME).c \
$(NET_BASE)modules.c \
$(NET_BASE)self_test.c \
$(STRUCTURES)measured_strings.c
$(STRUCTURES)char_map.c \
$(STRUCTURES)measured_strings.c \
$(NET_BASE)crc.c
 
NET_DEFS += -D NETWORKING_$(NETWORKING)
 
/branches/network/uspace/srv/net/crc.c
0,0 → 1,104
/*
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
* @{
*/
 
/** @file
* General CRC computation implementation.
*/
 
#include <sys/types.h>
 
#include "include/crc.h"
 
#define CRC_DIVIDER_BE 0x04C11DB7
 
#define CRC_DIVIDER_LE 0xEDB88320
 
uint32_t compute_crc32_le( uint32_t seed, uint8_t * data, int length ){
int index;
 
while( length >= 8 ){
seed ^= ( * data );
for( index = 0; index < 8; ++ index ){
if( seed & 1 ){
seed = ( seed >> 1 ) ^ (( uint32_t ) CRC_DIVIDER_LE );
}else{
seed >>= 1;
}
}
++ data;
length -= 8;
}
if( length > 0 ){
seed ^= ( * data ) >> ( 8 - length );
for( index = 0; index < length; ++ index ){
if( seed & 1 ){
seed = ( seed >> 1 ) ^ (( uint32_t ) CRC_DIVIDER_LE );
}else{
seed >>= 1;
}
}
length -= 8;
}
return seed;
}
 
uint32_t compute_crc32_be( uint32_t seed, uint8_t * data, int length ){
int index;
 
while( length >= 8 ){
seed ^= ( * data ) << 24;
for( index = 0; index < 8; ++ index ){
if( seed & 0x80000000 ){
seed = ( seed << 1 ) ^ (( uint32_t ) CRC_DIVIDER_BE );
}else{
seed <<= 1;
}
}
++ data;
length -= 8;
}
if( length > 0 ){
seed ^= (( * data ) & ( 0xFF << ( 8 - length ))) << 24;
for( index = 0; index < length; ++ index ){
if( seed & 0x80000000 ){
seed = ( seed << 1 ) ^ (( uint32_t ) CRC_DIVIDER_BE );
}else{
seed <<= 1;
}
}
length -= 8;
}
return seed;
}
 
/** @}
*/
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/branches/network/uspace/srv/net/configuration.h
45,7 → 45,7
* The NET_SELF_TEST has to be activated.
* @see measured_strings.h
*/
#define NET_SELF_TEST_MEASURED_STRINGS 1
#define NET_SELF_TEST_MEASURED_STRINGS 0
 
/** Activate the char map self test.
* The NET_SELF_TEST has to be activated.
71,6 → 71,12
*/
#define NET_SELF_TEST_GENERIC_CHAR_MAP 0
 
/** Activate the CRC computation self test.
* The NET_SELF_TEST has to be activated.
* @see crc.h
*/
#define NET_SELF_TEST_CRC 0
 
#endif
 
/** @}
/branches/network/uspace/srv/net/netif/lo/lo.c
167,16 → 167,16
 
ERROR_PROPAGATE( find_device( device_id, & device ));
if( device->state != NETIF_ACTIVE ) return EPERM;
next = packet;
do{
++ device->stats.tx_packets;
++ device->stats.rx_packets;
length = packet_get_data_length( packet );
length = packet_get_data_length( next );
device->stats.tx_bytes += length;
device->stats.rx_bytes += length;
next = pq_detach( packet );
nil_message( device, NET_NIL_RECEIVED, packet_get_id( packet ), PACKET_SELF );
packet = next;
}while( packet );
next = pq_next( next );
}while( next );
nil_message( device, NET_NIL_RECEIVED, packet_get_id( packet ), PACKET_SELF );
return EOK;
}
 
/branches/network/uspace/srv/net/self_test.c
41,10 → 41,11
#include <malloc.h>
#include <stdio.h>
 
#include "int_map.h"
#include "char_map.h"
#include "generic_char_map.h"
#include "measured_strings.h"
#include "include/crc.h"
#include "structures/int_map.h"
#include "structures/char_map.h"
#include "structures/generic_char_map.h"
#include "structures/measured_strings.h"
 
#include "self_test.h"
 
52,6 → 53,7
printf( "\n\t%s", ( name )); \
if(( function_call ) != ( result )){ \
printf( "\tERROR" ); \
error = 1; \
}else{ \
printf( "\tOK" ); \
} \
82,6 → 84,7
#endif
 
int self_test( void ){
int error = 0;
int * x, * y, * z, * u, * v, * w;
 
#if NET_SELF_TEST_MEASURED_STRINGS
88,7 → 91,7
measured_string_ref string;
 
printf( "\nMeasured strings test" );
string = measured_string_create_bulk( "I am a measured string!", -1 );
string = measured_string_create_bulk( "I am a measured string!", 0 );
printf( "\n%x, %s at %x of %d", string, string->value, string->value, string->length );
printf( "\nOK" );
#endif
132,10 → 135,11
TEST( "update ucho 3 einval", char_map_update( & cm, "ucho", 0, 3 ), EINVAL );
printf( "\nOK" );
 
if( error ) return EINVAL;
 
#endif
 
#if NET_SELF_TEST_INT_MAP
 
int_map_t im;
 
x = ( int * ) malloc( sizeof( int ));
185,10 → 189,11
TEST( "count -1", int_map_count( & im ), -1 );
printf( "\nOK" );
 
if( error ) return EINVAL;
 
#endif
 
#if NET_SELF_TEST_GENERIC_FIELD
 
int_field_t gf;
 
x = ( int * ) malloc( sizeof( int ));
235,10 → 240,11
TEST( "count -1", int_field_count( & gf ), -1 );
printf( "\nOK" );
 
if( error ) return EINVAL;
 
#endif
 
#if NET_SELF_TEST_GENERIC_CHAR_MAP
 
int_char_map_t icm;
 
x = ( int * ) malloc( sizeof( int ));
277,8 → 283,40
TEST( "add ucho z einval", int_char_map_add( & icm, "ucho", 0, z ), EINVAL );
printf( "\nOK" );
 
if( error ) return EINVAL;
 
#endif
 
#if NET_SELF_TEST_CRC
uint32_t value;
 
printf( "\nCRC computation test" );
value = ~ compute_crc32( ~ 0, "123456789", 8 * 9 );
TEST( "123456789", value, 0xCBF43926 );
printf( "\t=> %X", value );
value = ~ compute_crc32( ~ 0, "1", 8 );
TEST( "1", value, 0x83DCEFB7 );
printf( "\t=> %X", value );
value = ~ compute_crc32( ~ 0, "12", 8 * 2 );
TEST( "12", value, 0x4F5344CD );
printf( "\t=> %X", value );
value = ~ compute_crc32( ~ 0, "123", 8 * 3 );
TEST( "123", value, 0x884863D2 );
printf( "\t=> %X", value );
value = ~ compute_crc32( ~ 0, "1234", 8 * 4 );
TEST( "1234", value, 0x9BE3E0A3 );
printf( "\t=> %X", value );
value = ~ compute_crc32( ~ 0, "12345678", 8 * 8 );
TEST( "12345678", value, 0x9AE0DAAF );
printf( "\t=> %X", value );
value = ~ compute_crc32( ~ 0, "ahoj pane", 8 * 9 );
TEST( "ahoj pane", value, 0x5FC3D706 );
printf( "\t=> %X", value );
 
if( error ) return EINVAL;
 
#endif
 
return EOK;
}