/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; |
} |