Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4191 → Rev 4192

/branches/network/uspace/srv/net/networking/networking.c
39,8 → 39,6
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
#include <task.h>
#include <unistd.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
53,6 → 51,7
#include "../structures/char_map.h"
#include "../structures/generic_char_map.h"
#include "../structures/measured_strings.h"
#include "../structures/module_map.h"
#include "../structures/packet/packet.h"
#include "../structures/packet/packet_server.h"
 
93,9 → 92,6
#define IPC_GET_DEVICE( call ) ( device_id_t ) IPC_GET_ARG1( * call )
#define IPC_GET_COUNT( call ) ( int ) IPC_GET_ARG2( * call )
 
typedef struct module_struct module_t;
typedef module_t * module_ref;
 
typedef struct netif netif_t;
typedef netif_t * netif_ref;
 
105,17 → 101,6
 
GENERIC_CHAR_MAP_DECLARE( measured_strings, measured_string_t )
 
GENERIC_CHAR_MAP_DECLARE( modules, module_t )
 
struct module_struct{
task_id_t task_id;
services_t service;
int phone;
int usage;
char * name;
char * filename;
};
 
/** A present network interface device.
*/
struct netif{
157,7 → 142,6
};
 
void networking_print_name( void );
int add_module( module_ref * module, modules_ref modules, char * name, char * filename, services_t service, task_id_t task_id );
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 );
166,7 → 150,8
//int parse_line( measured_strings_ref configuration, char * line );
int add_configuration( measured_strings_ref configuration, const char * name, const char * value );
int read_configuration( void );
task_id_t spawn( char * fname );
int read_netif_configuration( char * name, netif_ref netif );
int start_device( netif_ref netif );
int startup( void );
device_id_t generate_new_device_id( void );
 
176,33 → 161,10
 
GENERIC_CHAR_MAP_IMPLEMENT( measured_strings, measured_string_t )
 
GENERIC_CHAR_MAP_IMPLEMENT( modules, module_t )
 
void networking_print_name( void ){
printf( NAME );
}
 
int add_module( module_ref * module, modules_ref modules, char * name, char * filename, services_t service, task_id_t task_id ){
ERROR_DECLARE;
 
module_ref tmp_module;
 
tmp_module = ( module_ref ) malloc( sizeof( module_t ));
if( ! tmp_module ) return ENOMEM;
tmp_module->task_id = task_id;
tmp_module->phone = 0;
tmp_module->usage = 0;
tmp_module->name = name;
tmp_module->filename = filename;
tmp_module->service = service;
if( ERROR_OCCURRED( modules_add( modules, tmp_module->name, 0, tmp_module ))){
free( tmp_module );
return ERROR_CODE;
}
if( module ) * module = tmp_module;
return EOK;
}
 
int networking_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
#ifdef NETWORKING_module
//TODO map to *_message
447,166 → 409,83
int read_configuration( void ){
ERROR_DECLARE;
 
netif_ref netif;
// read general configuration
ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "IPV", "4" ));
ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "MTU", "1500" ));
return EOK;
}
 
int read_netif_configuration( char * name, netif_ref netif ){
ERROR_DECLARE;
 
if( strncmp( name, "lo", 2 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", LO_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IL", IP_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_CONFIG", "static" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETMASK", "255.0.0.0" ));
}else if( strncmp( name, "ne2k", 4 ) == 0 ){
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NAME", "eth0" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETIF", DP8390_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NIL", ETHERNET_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IL", IP_NAME ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IRQ", "9" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IO", "300" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_CONFIG", "static" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "IP_ADDR", "10.0.2.5" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "NETMASK", "255.255.255.0" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "BROADCAST", "10.0.2.255" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "GATEWAY", "10.0.2.2" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "DNS1", "10.0.2.2" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "DNS2", "10.0.2.2" ));
ERROR_PROPAGATE( add_configuration( & netif->configuration, "ARP", "arp" ));
}
return EOK;
}
 
int start_device( netif_ref netif ){
ERROR_DECLARE;
 
measured_string_ref setting;
services_t internet_service;
int index;
int irq;
int io;
int mtu;
 
// read general configuration
ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "IPV", "4" ));
ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "MTU", "1500" ));
 
// read network interfaces configuration
 
netif = ( netif_ref ) malloc( sizeof( netif_t ));
if( ! netif ) return ENOMEM;
netif->id = generate_new_device_id();
ERROR_PROPAGATE( measured_strings_initialize( & netif->configuration ));
if( ERROR_OCCURRED( add_configuration( & netif->configuration, "NAME", "eth0" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NETIF", DP8390_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NIL", ETHERNET_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IL", IP_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IRQ", "9" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IO", "300" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IP_CONFIG", "STATIC" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IP_ADDR", "10.0.2.5" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NETMASK", "255.255.255.0" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "BROADCAST", "10.0.2.255" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "GATEWAY", "10.0.2.2" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "DNS1", "10.0.2.2" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "DNS2", "10.0.2.2" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "ARP", "ARP" ))){
measured_strings_destroy( & netif->configuration );
free( netif );
return ERROR_CODE;
}
/* if( ERROR_OCCURRED( add_configuration( & netif->configuration, "NAME", LO_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NETIF", LO_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IL", IP_NAME ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IP_CONFIG", "STATIC" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ))
|| ERROR_OCCURRED( add_configuration( & netif->configuration, "NETMASK", "255.0.0.0" ))){
measured_strings_destroy( & netif->configuration );
free( netif );
return ERROR_CODE;
}
*/ // mandatory name
setting = measured_strings_find( & netif->configuration, CONF_NAME, 0 );
if( ! setting ){
printf( "\nThe name is missing" );
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
netif->name = setting->value;
// mandatory netif
setting = measured_strings_find( & netif->configuration, CONF_NETIF, 0 );
if( ! setting ){
printf( "\nThe network interface driver is missing" );
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
netif->driver = modules_find( & networking_globals.modules, setting->value, 0 );
netif->driver = get_running_module( & networking_globals.modules, setting->value );
if( ! netif->driver ){
printf( "\nThe network interface driver is unknown" );
// TODO register the unknown one
measured_strings_destroy( & netif->configuration );
free( netif );
printf( "\nFailed to start the network interface driver %s", setting->value );
return EINVAL;
}
if( ! netif->driver->task_id ){
netif->driver->task_id = spawn( netif->driver->filename );
if( ! netif->driver->task_id ){
printf( "\nFailed to start the network interface driver" );
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
}
// optional network interface layer
setting = measured_strings_find( & netif->configuration, CONF_NIL, 0 );
if( setting ){
netif->nil = modules_find( & networking_globals.modules, setting->value, 0 );
netif->nil = get_running_module( & networking_globals.modules, setting->value );
if( ! netif->nil ){
printf( "\nThe network interface layer is unknown" );
// TODO register the unknown one
-- netif->driver->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
printf( "\nFailed to start the network interface layer %s", setting->value );
return EINVAL;
}
if( ! netif->nil->task_id ){
netif->nil->task_id = spawn( netif->nil->filename );
if( ! netif->nil->task_id ){
printf( "\nFailed to start the network interface layer" );
-- netif->driver->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
}
}else{
netif->nil = NULL;
}
// mandatory internet layer
setting = measured_strings_find( & netif->configuration, CONF_IL, 0 );
if( ! setting ){
printf( "\nThe internet layer is missing" );
-- netif->driver->usage;
-- netif->nil->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
netif->il = modules_find( & networking_globals.modules, setting->value, 0 );
netif->il = get_running_module( & networking_globals.modules, setting->value );
if( ! netif->il ){
printf( "\nThe internet layer is unknown" );
// TODO register the unknown one
-- netif->driver->usage;
-- netif->nil->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
printf( "\nFailed to start the internet layer %s", setting->value );
return EINVAL;
}
if( ! netif->il->task_id ){
netif->il->task_id = spawn( netif->il->filename );
if( ! netif->il->task_id ){
printf( "\nFailed to start the internet layer" );
-- netif->driver->usage;
-- netif->nil->usage;
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
}
index = netifs_add( & networking_globals.netifs, netif->id, netif );
if( index < 0 ){
free( netif );
return index;
}
if( ERROR_OCCURRED( char_map_add( & networking_globals.netif_names, netif->name, 0, index ))){
netifs_exclude_index( & networking_globals.netifs, index );
return ERROR_CODE;
}
// end of the static loopback initialization
// startup the loopback interface
if( ! netif->driver->phone ){
netif->driver->phone = connect_to_service( netif->driver->service );
}
setting = measured_strings_find( & netif->configuration, CONF_IRQ, 0 );
irq = setting ? strtol( setting->value, NULL, 10 ) : 0;
setting = measured_strings_find( & netif->configuration, CONF_IO, 0 );
io = setting ? strtol( setting->value, NULL, 16 ) : 0;
ERROR_PROPAGATE( async_req_3_0( netif->driver->phone, NET_NETIF_PROBE, netif->id, irq, io ));
++ netif->driver->usage;
if( netif->nil ){
if( ! netif->nil->phone ){
netif->nil->phone = connect_to_service( netif->nil->service );
}
setting = measured_strings_find( & netif->configuration, CONF_MTU, 0 );
if( ! setting ){
setting = measured_strings_find( & networking_globals.configuration, CONF_MTU, 0 );
613,53 → 492,72
}
mtu = setting ? strtol( setting->value, NULL, 10 ) : 0;
ERROR_PROPAGATE( async_req_3_0( netif->nil->phone, NET_NIL_DEVICE, netif->id, netif->driver->service, mtu ));
++ netif->nil->usage;
internet_service = netif->nil->service;
}else{
internet_service = netif->driver->service;
}
if( ! netif->il->phone ){
netif->il->phone = connect_to_service( netif->il->service );
}
// TODO IL_BUNDLE
ERROR_PROPAGATE( async_req_2_0( netif->il->phone, NET_IL_DEVICE, netif->id, internet_service ));
++ netif->il->usage;
// TODO startup?
ERROR_PROPAGATE( async_req_1_0( netif->driver->phone, NET_NETIF_START, netif->id ));
printf( "\nNew network interface started:\n\tname\t= %s\n\tid\t= %d\n\tdriver\t= %s\n\tnil\t= %s\n\til\t= %s", netif->name, netif->id, netif->driver->name, netif->nil ? netif->nil->name : NULL, netif->il->name );
return EOK;
}
 
task_id_t spawn( char * fname ){
char * argv[ 2 ];
// char * argv[ 4 ];
task_id_t res;
 
// printf( "Spawning %s\n", fname );
argv[ 0 ] = fname;
argv[ 1 ] = NULL;
res = task_spawn( fname, argv );
/* argv[ 0 ] = "/app/trace";
argv[ 1 ] = "+ti";
argv[ 2 ] = fname;
argv[ 3 ] = NULL;
res = task_spawn( "/app/trace", argv );
*/
if( res != 0 ){
/* Success */
usleep( 50000 );
}
return res;
}
 
int startup( void ){
ERROR_DECLARE;
 
// read configuration files
if( ERROR_OCCURRED( read_configuration())) return ERROR_CODE;
char * conf_files[] = { "lo", "ne2k" };
int count = sizeof( conf_files ) / sizeof( char * );
int index;
netif_ref netif;
int i;
measured_string_ref setting;
 
// start network interfaces and needed modules
// start_device( "/sbin/lo", "/sbin/dummy_link_layer" );
// TODO dynamic configuration
ERROR_PROPAGATE( read_configuration());
 
for( i = 0; i < count; ++ i ){
netif = ( netif_ref ) malloc( sizeof( netif_t ));
if( ! netif ) return ENOMEM;
 
netif->id = generate_new_device_id();
if( ! netif->id ) return EXDEV;
ERROR_PROPAGATE( measured_strings_initialize( & netif->configuration ));
// read configuration files
if( ERROR_OCCURRED( read_netif_configuration( conf_files[ i ], netif ))){
measured_strings_destroy( & netif->configuration );
free( netif );
return ERROR_CODE;
}
// mandatory name
setting = measured_strings_find( & netif->configuration, CONF_NAME, 0 );
if( ! setting ){
printf( "\nThe name is missing" );
measured_strings_destroy( & netif->configuration );
free( netif );
return EINVAL;
}
netif->name = setting->value;
// add to the netifs map
index = netifs_add( & networking_globals.netifs, netif->id, netif );
if( index < 0 ){
measured_strings_destroy( & netif->configuration );
free( netif );
return index;
}
// add to the netif names map
if( ERROR_OCCURRED( char_map_add( & networking_globals.netif_names, netif->name, 0, index ))
// start network interfaces and needed modules
|| ERROR_OCCURRED( start_device( netif ))){
measured_strings_destroy( & netif->configuration );
netifs_exclude_index( & networking_globals.netifs, index );
return ERROR_CODE;
}
// increment modules' usage
++ netif->driver->usage;
if( netif->nil ) ++ netif->nil->usage;
++ netif->il->usage;
printf( "\nNew network interface started:\n\tname\t= %s\n\tid\t= %d\n\tdriver\t= %s\n\tnil\t= %s\n\til\t= %s", netif->name, netif->id, netif->driver->name, netif->nil ? netif->nil->name : NULL, netif->il->name );
}
return EOK;
}
 
/branches/network/uspace/srv/net/networking/Makefile
43,6 → 43,7
$(NET_BASE)modules.c \
$(STRUCTURES)char_map.c \
$(STRUCTURES)measured_strings.c \
$(STRUCTURES)module_map.c \
$(STRUCTURES)packet/packet.c \
$(STRUCTURES)packet/packet_server.c
# $(NET_BASE)self_test.c