Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3990 → Rev 3991

/branches/network/uspace/srv/net/tl/tcp/tcp.c
65,7 → 65,7
printf( "OK\n" );
 
printf( "\nTCP - testing to send packet to IP:\t" );
packet = packet_get_5( tcp_globals.networking_phone, SERVICE_TCP, 6, 20, 30, 20 );
packet = packet_get_4( tcp_globals.networking_phone, 6, 20, 30, 20 );
if( ! packet ) return ENOMEM;
packet_copy_data( packet, "Hi, this is TCP", 16 );
ip_send( tcp_globals.ip_phone, -1, packet );
/branches/network/uspace/srv/net/networking/networking.c
149,7 → 149,6
 
void networking_print_name( void );
int add_module( module_ref * module, modules_ref modules, const char const * name, const char const * filename, services_t service, task_id_t task_id );
static void client_connection( ipc_callid_t iid, ipc_call_t * icall );
measured_string_ref configuration_find( measured_strings_ref configuration, const char * name );
int networking_start_module( async_client_conn_t client_connection );
int networking_initialize( void );
/branches/network/uspace/srv/net/messages.h
36,7 → 36,7
#ifndef __NET_MESSAGES_H__
#define __NET_MESSAGES_H__
 
#define NET_NETIF_COUNT 6
#define NET_NETIF_COUNT 8
#define NET_NET_COUNT 9
#define NET_NIL_COUNT 8
#define NET_ETH_COUNT 0
117,6 → 117,10
NET_NETIF_STATS,
/* ( device_id ) */
NET_NETIF_STOP,
/* */
NET_NETIF_SET_ADDR,
/* */
NET_NETIF_GET_ADDR,
/* () not supported, registers new device */
NET_NET_DEVICE = NET_NET_FIRST,
/* ( NULL, count ), measured_strings_send( names ), measured_strings_return( values ) */
135,24 → 139,20
NET_NET_STOP,
/* ( device_id ) ipc_data_read( stats ) */
NET_NET_STATS,
/* ( device_id, driver_service ) */
/* ( device_id, driver_service, mtu ) */
NET_NIL_DEVICE = NET_NIL_FIRST,
/* ( device_id, state ) */
NET_NIL_DEVICE_STATE,
/* ( device_id, mtu ) */
NET_NIL_MTU,
/* ( device_id ), packet_send */
NET_NIL_RECEIVED,
/* ( device_id ), packet_send */
NET_NIL_SEND,
/* ( device_id ) -> prefix, content, suffix */
/* ( device_id ) -> addr, prefix, content, suffix */
NET_NIL_PACKET_SPACE,
/* ( device_id ), measured_strings_return( hardware address ) */
NET_NIL_ADDR,
/* ( device_id ), measured_strings_return( broadcast address ) */
NET_NIL_BROADCAST_ADDR,
/* ( service ), protocol */
// NET_NIL_PROTOCOL,
/* ( device_id, nil_service ) */
NET_IL_DEVICE = NET_IL_FIRST,
/* ( device_id, state ) */
173,7 → 173,7
/* () */
NET_ARP_CLEAN_CACHE,
NET_PACKET_CREATE_1 = NET_PACKET_FIRST,
NET_PACKET_CREATE_5,
NET_PACKET_CREATE_4,
NET_PACKET_GET,
NET_PACKET_GET_SIZE,
NET_PACKET_RELEASE
/branches/network/uspace/srv/net/il/arp/arp.c
35,9 → 35,9
* @see arp.h
*/
 
#include <as.h>
#include <async.h>
#include <malloc.h>
#include <rwlock.h>
#include <stdio.h>
#include <string.h>
 
160,7 → 160,13
GENERIC_CHAR_MAP_IMPLEMENT( arp_addr, measured_string_t )
 
int arp_initialize( void ){
return arp_cache_initialize( & arp_globals.cache );
ERROR_DECLARE;
 
rwlock_initialize( & arp_globals.lock );
rwlock_write_lock( & arp_globals.lock );
ERROR_PROPAGATE( arp_cache_initialize( & arp_globals.cache ));
rwlock_write_unlock( & arp_globals.lock );
return EOK;
}
 
int arp_proto_create( arp_proto_ref * proto, services_t service, measured_string_ref address ){
187,10 → 193,14
ipcarg_t result;
arp_proto_ref proto;
 
rwlock_write_lock( & arp_globals.lock );
// an existing device?
device = arp_cache_find( & arp_globals.cache, device_id );
if( device ){
if( device->service != service ) return EEXIST;
if( device->service != service ){
rwlock_write_unlock( & arp_globals.lock );
return EEXIST;
}
proto = arp_protos_find( & device->protos, protocol );
if( proto ){
free( proto->addr );
198,8 → 208,12
proto->addr = address;
proto->addr_data = address->value;
}else{
ERROR_PROPAGATE( arp_proto_create( & proto, protocol, address ));
if( ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
rwlock_write_unlock( & arp_globals.lock );
return ERROR_CODE;
}
if( ERROR_OCCURRED( arp_protos_add( & device->protos, proto->service, proto ))){
rwlock_write_unlock( & arp_globals.lock );
free( proto );
return ERROR_CODE;
}
208,14 → 222,19
}else{
// create a new device
device = ( arp_device_ref ) malloc( sizeof( arp_device_t ));
if( ! device ) return ENOMEM;
if( ! device ){
rwlock_write_unlock( & arp_globals.lock );
return ENOMEM;
}
device->device_id = device_id;
if( ERROR_OCCURRED( arp_protos_initialize( & device->protos ))
|| ERROR_OCCURRED( arp_proto_create( & proto, protocol, address ))){
rwlock_write_unlock( & arp_globals.lock );
free( device );
return ERROR_CODE;
}
if( ERROR_OCCURRED( arp_protos_add( & device->protos, proto->service, proto ))){
rwlock_write_unlock( & arp_globals.lock );
arp_protos_destroy( & device->protos );
free( device );
return ERROR_CODE;
225,6 → 244,7
device->phone = bind_service( device->service, device->device_id, SERVICE_ARP, 0, arp_receiver );
// get packet dimensions
if( ERROR_OCCURRED( async_req_1_4( device->phone, NET_NIL_PACKET_SPACE, device_id, & device->addr_len, & device->prefix, & device->content, & device->suffix ))){
rwlock_write_unlock( & arp_globals.lock );
arp_protos_destroy( & device->protos );
free( device );
return ERROR_CODE;
232,6 → 252,7
// get hardware address
message = async_send_1( device->phone, NET_NIL_ADDR, device->device_id, & answer );
if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->addr, & device->addr_data, 1 ))){
rwlock_write_unlock( & arp_globals.lock );
arp_protos_destroy( & device->protos );
free( device );
async_wait_for( message, NULL );
239,6 → 260,7
}
async_wait_for( message, & result );
if( ERROR_OCCURRED( result )){
rwlock_write_unlock( & arp_globals.lock );
free( device->addr );
free( device->addr_data );
arp_protos_destroy( & device->protos );
248,6 → 270,7
// get broadcast address
message = async_send_1( device->phone, NET_NIL_BROADCAST_ADDR, device->device_id, & answer );
if( ERROR_OCCURRED( measured_strings_return( device->phone, & device->broadcast_addr, & device->broadcast_data, 1 ))){
rwlock_write_unlock( & arp_globals.lock );
free( device->addr );
free( device->addr_data );
arp_protos_destroy( & device->protos );
259,6 → 282,7
// add to the cache
if( ERROR_OCCURRED( result )
|| ERROR_OCCURRED( arp_cache_add( & arp_globals.cache, device->device_id, device ))){
rwlock_write_unlock( & arp_globals.lock );
free( device->addr );
free( device->addr_data );
free( device->broadcast_addr );
268,6 → 292,7
return ERROR_CODE;
}
}
rwlock_write_unlock( & arp_globals.lock );
return EOK;
}
 
280,19 → 305,33
arp_header_ref header;
 
if( ! target ) return NULL;
rwlock_read_lock( & arp_globals.lock );
device = arp_cache_find( & arp_globals.cache, device_id );
if( ! device ) return NULL;
if( ! device ){
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
proto = arp_protos_find( & device->protos, protocol );
if(( ! proto ) || ( proto->addr->length != target->length )) return NULL;
if(( ! proto ) || ( proto->addr->length != target->length )){
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
addr = arp_addr_find( & proto->addresses, target->value, target->length );
if( addr ) return addr;
if( addr ){
rwlock_read_unlock( & arp_globals.lock );
return addr;
}
// ARP packet content size = header + ( address + translation ) * 2
length = 8 + ( CONVERT_SIZE( char, uint8_t, proto->addr->length ) + CONVERT_SIZE( char, uint8_t, device->addr->length )) * 2;
if( length > device->content ){
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
packet = packet_get_5( arp_globals.networking_phone, SERVICE_ARP, device->addr_len, device->prefix, length, device->suffix );
if( ! packet ) return NULL;
packet = packet_get_4( arp_globals.networking_phone, device->addr_len, device->prefix, length, device->suffix );
if( ! packet ){
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
header = ( arp_header_ref ) packet_suffix( packet, length );
header->hardware = device->hardware;
header->hardware_length = device->addr->length;
309,6 → 348,7
memcpy((( uint8_t * ) header ) + length, target->value, target->length );
packet_set_addr( packet, ( uint8_t * ) device->addr->value, ( uint8_t * ) device->broadcast_addr->value, CONVERT_SIZE( char, uint8_t, device->addr->length ));
async_msg_3( device->phone, NET_NETIF_SEND, device_id, SERVICE_ARP, packet_get_id( packet ));
rwlock_read_unlock( & arp_globals.lock );
return NULL;
}
 
319,14 → 359,8
arp_header_ref header;
arp_device_ref device;
arp_proto_ref proto;
// arp_addr_ref addr;
measured_string_ref hw_source;
/* measured_string_t proto_target;
aid_t message;
ipcarg_t result;
int index;
ipc_call_t answer;
*/ uint8_t * src_hw;
uint8_t * src_hw;
uint8_t * src_proto;
uint8_t * des_hw;
uint8_t * des_proto;
333,13 → 367,23
 
length = packet_get_data_length( packet );
if( length <= sizeof( arp_header_t )) return EINVAL;
rwlock_read_lock( & arp_globals.lock );
device = arp_cache_find( & arp_globals.cache, device_id );
if( ! device ) return ENOENT;
if( ! device ){
rwlock_read_unlock( & arp_globals.lock );
return ENOENT;
}
header = ( arp_header_ref ) packet_get_data( packet );
if( header->hardware != device->hardware ) return EINVAL;
if( length < sizeof( arp_header_t ) + ( header->hardware_length + header->protocol_length ) * 2 ) return EINVAL;
if(( header->hardware != device->hardware )
|| ( length < sizeof( arp_header_t ) + ( header->hardware_length + header->protocol_length ) * 2 )){
rwlock_read_unlock( & arp_globals.lock );
return EINVAL;
}
proto = arp_protos_find( & device->protos, protocol_unmap( device->service, header->protocol ));
if( ! proto ) return ENOENT;
if( ! proto ){
rwlock_read_unlock( & arp_globals.lock );
return ENOENT;
}
src_hw = (( uint8_t * ) header ) + sizeof( arp_header_t );
src_proto = src_hw + header->hardware_length;
des_hw = src_proto + header->protocol_length;
347,48 → 391,41
hw_source = arp_addr_find( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ));
// exists?
if( hw_source ){
if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )) return EINVAL;
if( hw_source->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){
rwlock_read_unlock( & arp_globals.lock );
return EINVAL;
}
memcpy( hw_source->value, src_hw, hw_source->length );
}
// is my protocol address?
// TODO query protocol module?
/* proto_target.value = des_proto;
proto_target.length = header->protocol_length;
// TODO send necessary?
message = async_send_0( proto->phone, NET_IL_MY_ADDR, & answer );
if( ERROR_OCCURRED( measured_strings_send( device->phone, & proto_target, 1 ))){
async_wait_for( message, NULL );
return ERROR_CODE;
if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )){
rwlock_read_unlock( & arp_globals.lock );
return EINVAL;
}
async_wait_for( message, & result );
if( result == EOK ){
*/ if( proto->addr->length != CONVERT_SIZE( uint8_t, char, header->hardware_length )) return EINVAL;
if( ! strncmp( proto->addr->value, ( char * ) des_proto, proto->addr->length )){
// not already upadted?
if( ! hw_source ){
hw_source = measured_string_create_bulk(( char * ) src_hw, CONVERT_SIZE( uint8_t, char, header->hardware_length ));
if( ! hw_source ) return ENOMEM;
ERROR_PROPAGATE( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source ));
if( ! hw_source ){
rwlock_read_unlock( & arp_globals.lock );
return ENOMEM;
}
if( ERROR_OCCURRED( arp_addr_add( & proto->addresses, ( char * ) src_proto, CONVERT_SIZE( uint8_t, char, header->protocol_length ), hw_source ))){
rwlock_read_unlock( & arp_globals.lock );
return ERROR_CODE;
}
}
if( header->operation == ARPOP_REQUEST ){
header->operation = ARPOP_REPLY;
/* for( index = 0; index + header->hardware_length < header->protocol_length; index += header->hardware_length ){
memcpy( src_hw, src_proto + index, header->hardware_length );
memcpy( src_proto + index, des_proto + index, header->hardware_length );
memcpy( des_proto + index, src_hw, header->hardware_length );
}
memcpy( src_hw, src_proto + index, header->hardware_length - header->protocol_length );
memcpy( src_proto + index, des_proto + index, header->hardware_length - header->protocol_length );
memcpy( des_proto + index, src_hw, header->hardware_length - header->protocol_length );
memcpy( src_hw, des_hw, header->hardware_length );
memcpy( des_hw, hw_source->value, hw_source->length );
*/ memcpy( des_proto, src_proto, header->protocol_length );
memcpy( des_proto, src_proto, header->protocol_length );
memcpy( src_proto, proto->addr->value, header->protocol_length );
memcpy( src_hw, des_hw, header->hardware_length );
memcpy( des_hw, hw_source->value, header->hardware_length );
packet_set_addr( packet, src_hw, des_hw, header->hardware_length );
async_msg_3( device->phone, NET_NETIF_SEND, device_id, SERVICE_ARP, packet_get_id( packet ));
rwlock_read_unlock( & arp_globals.lock );
}else{
rwlock_read_unlock( & arp_globals.lock );
packet_release( arp_globals.networking_phone, packet_get_id( packet ));
}
}
398,9 → 435,14
int arp_clear_device_message( device_id_t device_id ){
arp_device_ref device;
 
rwlock_write_lock( & arp_globals.lock );
device = arp_cache_find( & arp_globals.cache, device_id );
if( ! device ) return ENOENT;
if( ! device ){
rwlock_write_unlock( & arp_globals.lock );
return ENOENT;
}
clear_device( device );
rwlock_write_unlock( & arp_globals.lock );
return EOK;
}
 
423,6 → 465,7
int count;
arp_device_ref device;
 
rwlock_write_lock( & arp_globals.lock );
count = arp_cache_count( & arp_globals.cache );
while( count > 0 ){
device = arp_cache_get_index( & arp_globals.cache, count );
433,6 → 476,7
}
}
arp_cache_clear( & arp_globals.cache );
rwlock_write_lock( & arp_globals.lock );
return EOK;
}
 
477,7 → 521,8
while( true ){
switch( IPC_GET_METHOD( * icall )){
case NET_IL_DEVICE_STATE:
//TODO clear device if off?
// do nothing - keep the cache
ipc_answer_0( iid, EOK );
break;
case NET_IL_RECEIVED:
if( ! ERROR_OCCURRED( packet_translate( arp_globals.networking_phone, & packet, IPC_GET_PACKET( icall )))){
/branches/network/uspace/srv/net/il/arp/arp.h
37,6 → 37,8
#ifndef __NET_ARP_H__
#define __NET_ARP_H__
 
#include <rwlock.h>
 
#include <ipc/ipc.h>
 
#include "../../netif/device.h"
141,7 → 143,6
/** Protocol service.
*/
services_t service;
// int phone;
/** Actual device protocol address.
*/
measured_string_ref addr;
159,6 → 160,9
/** Networking module phone.
*/
int networking_phone;
/** Safety lock.
*/
rwlock_t lock;
/** ARP address cache.
*/
arp_cache_t cache;
/branches/network/uspace/srv/net/il/ip/ip_header.h
51,7 → 51,6
*/
typedef ip_header_t * ip_header_ref;
 
 
/** Internet header.
* The variable options should be included after the header itself and indicated by the increased header length value.
*/
/branches/network/uspace/srv/net/il/ip/ip.c
33,7 → 33,6
/** @file
*/
 
#include <as.h>
#include <async.h>
#include <errno.h>
#include <stdio.h>
/branches/network/uspace/srv/net/netif/device.h
77,6 → 77,15
NETIF_CARRIER_LOST
};
 
/** \todo
*/
#define NIFF_UP ( 1 << 0 )
#define NIFF_NOARP ( 1 << 1 )
#define NIFF_LOOPBACK ( 1 << 2 )
#define NIFF_BROADCAST ( 1 << 3 )
#define NIFF_PROMISC ( 1 << 4 )
#define NIFF_MULTICAST ( 1 << 5 )
 
/** Device usage statistics.
* Based on linux_kernel/include/linux/netdevice.h.
*/
/branches/network/uspace/srv/net/netif/lo/lo.c
163,27 → 163,20
 
device_ref device;
size_t length;
packet_t received;
packet_t next;
 
ERROR_PROPAGATE( find_device( device_id, & device ));
if( device->state != NETIF_ACTIVE ) return EPERM;
++ device->stats.tx_packets;
++ device->stats.rx_packets;
length = packet_get_data_length( packet );
device->stats.tx_bytes += length;
device->stats.rx_bytes += length;
received = packet_copy( netif_globals.networking_phone, SERVICE_LO, packet );
packet_release( netif_globals.networking_phone, packet_get_id( packet ));
if( ! received ){
++ device->stats.rx_dropped;
return EOK;
}
nil_message( device, NET_NIL_RECEIVED, packet_get_id( received ), NULL );
// message = async_send_1( device->nil_phone, NET_NIL_RECEIVED, ( device_id ), & answer );
// if( ERROR_OCCURRED( packet_send( received, device->nil_phone ))){
// ++ device->stats.rx_dropped;
// }
// if( result != EOK ) ++ device->stats.rx_dropped;
do{
++ device->stats.tx_packets;
++ device->stats.rx_packets;
length = packet_get_data_length( packet );
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 );
return EOK;
}