/branches/network/uspace/srv/net/crc.c |
---|
File deleted |
Property changes: |
Deleted: svn:eol-style |
-native |
\ No newline at end of property |
/branches/network/uspace/srv/net/nil/eth/eth.c |
---|
48,8 → 48,6 |
#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" |
64,9 → 62,10 |
#include "eth_module.h" |
#define ETH_PREFIX ( sizeof( eth_header_t ) + sizeof( eth_header_lsap_t ) + sizeof( eth_header_snap_t )) |
#define ETH_SUFFIX sizeof( eth_fcs_t ) |
#define ETH_MAX_CONTENT 1500 |
#define ETH_SUFFIX 4 |
#define ETH_MAX_CONTENT ( ETH_MIN_PROTO - 1 ) |
#define ETH_MIN_CONTENT 46 |
#define ETH_PADDING ETH_SUFFIX |
/** Returns the device identifier message parameter. |
*/ |
123,8 → 122,6 |
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; |
204,76 → 201,55 |
return EOK; |
} |
eth_proto_ref eth_proccess_packet( packet_t packet ){ |
int eth_receive_message( device_id_t device_id, packet_t packet ){ |
ERROR_DECLARE; |
eth_header_ex_ref header; |
size_t length; |
int type; |
size_t prefix; |
size_t suffix; |
eth_fcs_ref fcs; |
eth_proto_ref proto; |
size_t size; |
length = packet_get_data_length( packet ); |
if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_SUFFIX ) return NULL; |
if( length <= sizeof( eth_header_t ) + ETH_MIN_CONTENT + ETH_PADDING ) return EINVAL; |
// TODO check CRC padding? |
header = ( eth_header_ex_ref ) packet_get_data( packet ); |
type = ntohs( header->header.ethertype ); |
if( type >= ETH_MIN_PROTO ){ |
// DIX Ethernet |
prefix = sizeof( eth_header_t ); |
suffix = sizeof( eth_fcs_t ); |
fcs = (( void * ) header ) + length - suffix; |
}else if( type <= ETH_MAX_CONTENT ){ |
size = sizeof( eth_header_t ); |
}else{ |
// TODO check length? |
// translate "LSAP" values |
if(( header->lsap.dsap == ETH_LSAP_GLSAP ) && ( header->lsap.ssap == ETH_LSAP_GLSAP )){ |
if(( header->lsap.dsap == ETH_RAW ) && ( header->lsap.ssap == ETH_RAW )){ |
// raw packet |
// discard |
return NULL; |
return EINVAL; |
}else if(( header->lsap.dsap == ETH_LSAP_SNAP ) && ( header->lsap.ssap == ETH_LSAP_SNAP )){ |
// IEEE 802.3 + 802.2 + LSAP + SNAP |
// IEEE 802.3 SNAP |
// organization code not supported |
type = ntohs( header->snap.ethertype ); |
prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t) + sizeof( eth_header_snap_t); |
size = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t) + sizeof( eth_header_snap_t); |
}else{ |
// IEEE 802.3 + 802.2 LSAP |
type = lsap_map( header->lsap.dsap ); |
prefix = sizeof( eth_header_t ) + sizeof( eth_header_lsap_t); |
// TODO lsap numbers |
type = header->lsap.dsap; |
size = 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; |
} |
// TODO compute crc with fcs to erase? |
if(( ~ compute_crc32( ~ 0, & header->header.dest, ((( void * ) fcs ) - (( void * ) & header->header.dest )) * 8 )) != ( * fcs )){ |
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; |
} |
if( ERROR_OCCURRED( packet_set_addr( packet, header->header.src, header->header.dest, ETH_ADDR )) |
|| ERROR_OCCURRED( packet_trim( packet, prefix, suffix ))){ |
return NULL; |
|| ERROR_OCCURRED( packet_trim( packet, size, ETH_PADDING ))){ |
rwlock_write_unlock( & eth_globals.protos_lock ); |
return ERROR_CODE; |
} |
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 ); |
async_msg_2( proto->phone, NET_IL_RECEIVED, device_id, packet_get_id( packet )); |
rwlock_write_unlock( & eth_globals.protos_lock ); |
return EOK; |
} |
291,7 → 267,7 |
rwlock_write_unlock( & eth_globals.devices_lock ); |
* addr_len = ETH_ADDR; |
* prefix = ETH_PREFIX; |
* suffix = ETH_MIN_CONTENT + ETH_SUFFIX; |
* suffix = ETH_SUFFIX; |
return EOK; |
} |
347,14 → 323,15 |
return EOK; |
} |
int eth_prepare_packet( packet_t packet, uint8_t * src_addr, int ethertype ){ |
int eth_send_message( device_id_t device_id, packet_t packet, services_t sender ){ |
ERROR_DECLARE; |
eth_device_ref device; |
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; |
363,14 → 340,12 |
length = packet_get_addr( packet, & src, & dest ); |
if( length < 0 ) return length; |
if( length < ETH_ADDR ) return EINVAL; |
memcpy( header->header.src, src_addr, ETH_ADDR ); |
memcpy( & header->header.dest, dest, ETH_ADDR ); |
// TODO src set? |
// TODO set addresses |
length = packet_get_data_length( packet ); |
if( length > ETH_MAX_CONTENT ) return EINVAL; |
if( length < ETH_MIN_CONTENT ){ |
padding = packet_suffix( packet, ETH_MIN_CONTENT - length ); |
if( ! padding ) return ENOMEM; |
memset( padding, 0, ETH_MIN_CONTENT - length ); |
// TODO pad zeros |
} |
header->header.ethertype = htons( length ); |
header->lsap.dsap = 0xAA; |
377,47 → 352,15 |
header->lsap.ssap = header->lsap.dsap; |
header->lsap.ctrl = 0; |
for( i = 0; i < 3; ++ i ) header->snap.proto[ i ] = 0; |
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; |
header->snap.ethertype = htons( protocol_map( SERVICE_ETHERNET, sender )); |
if( ! header ) return ENOENT; |
// TODO eth padding |
if( ! packet_suffix( packet, ETH_PADDING )){ |
return ENOMEM; |
} |
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 ); |
rwlock_write_lock( & eth_globals.devices_lock ); |
rwlock_write_unlock( & eth_globals.devices_lock ); |
return EOK; |
} |
/branches/network/uspace/srv/net/nil/eth/Makefile |
---|
37,7 → 37,6 |
$(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,8 → 44,12 |
#define ETH_PREAMBLE 0x55 |
#define ETH_SFD 0xD5 |
#define ETH_SFD 0xF5 |
#define ETH_LSAP_SNAP 0xAA |
#define ETH_RAW 0xFF |
/** Type definition of the Ethernet header with all the extensions. |
* @see eth_header_ex |
*/ |
154,14 → 158,6 |
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 |
---|
File deleted |
Property changes: |
Deleted: svn:eol-style |
-native |
\ No newline at end of property |
/branches/network/uspace/srv/net/include/crc.h |
---|
File deleted |
Property changes: |
Deleted: svn:eol-style |
-native |
\ No newline at end of property |
/branches/network/uspace/srv/net/include/ethernet_protocols.h |
---|
39,9 → 39,8 |
#define __NET_ETHERNET_PROTOCOLS_H__ |
/** Ethernet minimal protocol number. |
* According to the IEEE 802.3 specification. |
*/ |
#define ETH_MIN_PROTO 0x0600 /*1536*/ |
#define ETH_MIN_PROTO 1501 |
/** Ethernet loopback packet protocol type. |
*/ |
/branches/network/uspace/srv/net/include/protocol_map.h |
---|
39,7 → 39,6 |
#include <ipc/services.h> |
#include "ethernet_lsap.h" |
#include "ethernet_protocols.h" |
/** Maps the internetwork layer service to the network interface layer type. |
86,22 → 85,6 |
} |
} |
/** 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/networking/startup/Makefile |
---|
41,9 → 41,7 |
$(NAME).c \ |
$(NET_BASE)modules.c \ |
$(NET_BASE)self_test.c \ |
$(STRUCTURES)char_map.c \ |
$(STRUCTURES)measured_strings.c \ |
$(NET_BASE)crc.c |
$(STRUCTURES)measured_strings.c |
NET_DEFS += -D NETWORKING_$(NETWORKING) |
/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( next ); |
length = packet_get_data_length( packet ); |
device->stats.tx_bytes += length; |
device->stats.rx_bytes += length; |
next = pq_next( next ); |
}while( next ); |
nil_message( device, NET_NIL_RECEIVED, packet_get_id( packet ), PACKET_SELF ); |
next = pq_detach( packet ); |
nil_message( device, NET_NIL_RECEIVED, packet_get_id( packet ), PACKET_SELF ); |
packet = next; |
}while( packet ); |
return EOK; |
} |
/branches/network/uspace/srv/net/structures/packet/packet.c |
---|
250,15 → 250,5 |
} |
} |
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,10 → 193,9 |
*/ |
packet_t packet_get_1( int phone, size_t content ); |
/** 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. |
/** 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. |
* @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,22 → 129,6 |
*/ |
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/configuration.h |
---|
45,7 → 45,7 |
* The NET_SELF_TEST has to be activated. |
* @see measured_strings.h |
*/ |
#define NET_SELF_TEST_MEASURED_STRINGS 0 |
#define NET_SELF_TEST_MEASURED_STRINGS 1 |
/** Activate the char map self test. |
* The NET_SELF_TEST has to be activated. |
71,12 → 71,6 |
*/ |
#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/self_test.c |
---|
41,11 → 41,10 |
#include <malloc.h> |
#include <stdio.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 "int_map.h" |
#include "char_map.h" |
#include "generic_char_map.h" |
#include "measured_strings.h" |
#include "self_test.h" |
53,7 → 52,6 |
printf( "\n\t%s", ( name )); \ |
if(( function_call ) != ( result )){ \ |
printf( "\tERROR" ); \ |
error = 1; \ |
}else{ \ |
printf( "\tOK" ); \ |
} \ |
84,7 → 82,6 |
#endif |
int self_test( void ){ |
int error = 0; |
int * x, * y, * z, * u, * v, * w; |
#if NET_SELF_TEST_MEASURED_STRINGS |
91,7 → 88,7 |
measured_string_ref string; |
printf( "\nMeasured strings test" ); |
string = measured_string_create_bulk( "I am a measured string!", 0 ); |
string = measured_string_create_bulk( "I am a measured string!", -1 ); |
printf( "\n%x, %s at %x of %d", string, string->value, string->value, string->length ); |
printf( "\nOK" ); |
#endif |
135,11 → 132,10 |
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 )); |
189,11 → 185,10 |
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 )); |
240,11 → 235,10 |
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 )); |
283,40 → 277,8 |
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; |
} |