Subversion Repositories HelenOS

Rev

Rev 3466 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3466 Rev 3666
Line 32... Line 32...
32
 
32
 
33
/** @file
33
/** @file
34
 */
34
 */
35
 
35
 
36
#include <async.h>
36
#include <async.h>
-
 
37
#include <ctype.h>
37
#include <errno.h>
38
#include <errno.h>
-
 
39
#include <malloc.h>
38
#include <stdio.h>
40
#include <stdio.h>
39
#include <task.h>
41
#include <task.h>
-
 
42
//#include <thread.h>
-
 
43
#include <unistd.h>
40
#include <ipc/ipc.h>
44
#include <ipc/ipc.h>
41
#include <ipc/services.h>
45
#include <ipc/services.h>
42
//#include <sys/mman.h>
46
//#include <sys/mman.h>
43
 
47
 
-
 
48
#include "../char_map.h"
44
#include "../modules.h"
49
#include "../err.h"
-
 
50
#include "../generic_char_map.h"
-
 
51
#include "../measured_strings.h"
45
#include "../messages.h"
52
#include "../messages.h"
-
 
53
#include "../modules.h"
-
 
54
//#include "../self_test.h"
-
 
55
 
-
 
56
#include "../netif/netif_device_id_type.h"
46
 
57
 
47
#ifdef NETWORKING_module
58
#ifdef NETWORKING_module
48
 
59
 
49
    #include "../ip/ip.h"
60
    #include "../ip/ip.h"
50
    #include "../tcp/tcp.h"
61
    #include "../tcp/tcp.h"
51
 
62
 
52
#endif
63
#endif
53
 
64
 
54
#define IS_IN_INTERVAL( item, first_inclusive, last_exclusive ) ((( item ) >= ( first_inclusive )) && (( item ) < ( last_exclusive )))
-
 
55
 
-
 
56
#define IS_NET_MESSAGE( call )          IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_FIRST, NET_LAST )
65
#define LO_NAME             "lo"
57
#define IS_NET_NETWORKING_MESSAGE( call )   IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_NETWORKING_FIRST, NET_NETWORKING_LAST )
-
 
58
#define IS_NET_IP_MESSAGE( call )       IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_IP_FIRST, NET_IP_LAST )
66
#define LO_FILENAME         "/sbin/lo"
59
#define IS_NET_ARP_MESSAGE( call )      IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_ARP_FIRST, NET_ARP_LAST )
67
#define DP8390_ISA_NAME         "dp8390_isa"
60
#define IS_NET_RARP_MESSAGE( call )     IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_RARP_FIRST, NET_RARP_LAST )
68
#define DP8390_ISA_FILENAME     "/sbin/dp8380_isa"
61
#define IS_NET_UDP_MESSAGE( call )      IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_UDP_FIRST, NET_UDP_LAST )
69
#define ETHERNET_NAME           "ethernet"
62
#define IS_NET_TCP_MESSAGE( call )      IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_TCP_FIRST, NET_TCP_LAST )
70
#define ETHERNET_FILENAME       "/sbin/ethernet"
63
#define IS_NET_SOCKET_MESSAGE( call )       IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_SOCKET_FIRST, NET_SOCKET_LAST )
71
#define IP_NAME             "ip"
64
#define IS_NET_ETHERNET_MESSAGE( call )     IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_ETHERNET_FIRST, NET_SOCKET_LAST )
72
#define IP_FILENAME         "/sbin/ip"
65
 
73
 
66
int networking_initialize( void );
74
typedef struct module_struct    module_t;
67
static void client_connection( ipc_callid_t iid, ipc_call_t * icall );
75
typedef module_t *      module_ref;
-
 
76
 
68
int main( int argc, char * argv[] );
77
typedef struct netif        netif_t;
69
int spawn( const char * fname );
78
typedef netif_t *       netif_ref;
-
 
79
 
70
int networking_call( ipc_callid_t callid );
80
typedef struct networking_globals   networking_globals_t;
-
 
81
 
-
 
82
DEVICE_MAP_DECLARE( netifs, netif_t )
-
 
83
 
71
int networking_message( ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3 );
84
GENERIC_CHAR_MAP_DECLARE( measured_strings, measured_string_t )
72
 
85
 
73
int networking_call( ipc_callid_t callid ){
86
GENERIC_CHAR_MAP_DECLARE( modules, module_t )
-
 
87
 
-
 
88
struct module_struct{
-
 
89
    task_id_t   task_id;
-
 
90
    services_t  service;
-
 
91
    int     phone;
74
    return EOK;
92
    int     usage;
-
 
93
    const char *    name;
-
 
94
    const char *    filename;
75
}
95
};
76
 
96
 
77
int networking_message( ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3 ){
97
/** A present network interface device.
-
 
98
 */
78
    switch( method ){
99
struct netif{
79
        case IPC_M_PHONE_HUNGUP:
100
    /** A system-unique network interface identifier.
-
 
101
     */
80
            return EOK;
102
    netif_device_id_t   id;
-
 
103
    /** A serving network interface driver module index.
81
    }
104
     */
82
    return ENOTSUP;
105
    module_ref      driver_module;
-
 
106
    /** A serving link layer module index.
83
}
107
     */
-
 
108
    module_ref      link_layer_module;
-
 
109
    /** A serving internet layer module index.
84
 
110
     */
-
 
111
    module_ref      internet_layer_module;
85
int spawn(const char *fname)
112
    /** A system-unique network interface name.
86
{
113
     */
87
    const char *argv[2];
114
    char *          name;
-
 
115
    /** Configuration.
88
    int res;
116
     */
-
 
117
    measured_strings_t  configuration;
-
 
118
};
89
 
119
 
-
 
120
/** A networking module global variables.
-
 
121
 */
-
 
122
struct networking_globals{
-
 
123
    /** Present network interfaces.
-
 
124
     */
-
 
125
    netifs_t        netifs;
-
 
126
    /** Network interface structure indices by names.
-
 
127
     */
-
 
128
    char_map_t      netif_names;
-
 
129
    /** Available modules.
-
 
130
     */
-
 
131
    modules_t       modules;
-
 
132
    /** Global configuration.
-
 
133
     */
-
 
134
    measured_strings_t  configuration;
-
 
135
};
-
 
136
 
-
 
137
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 );
-
 
138
static void client_connection( ipc_callid_t iid, ipc_call_t * icall );
-
 
139
measured_string_ref configuration_find( measured_strings_ref configuration, const char * name );
-
 
140
int     main( int argc, char * argv[] );
-
 
141
int     networking_call( ipc_callid_t callid );
-
 
142
int     networking_initialize( void );
-
 
143
int     networking_message( ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 );
-
 
144
//int       parse_line( measured_strings_ref configuration, char * line );
-
 
145
int     add_configuration( measured_strings_ref configuration, const char * name, const char * value );
-
 
146
int     read_configuration( void );
90
    printf("Spawning %s\n", fname);
147
task_id_t   spawn( const char * fname );
-
 
148
int     startup( void );
-
 
149
netif_device_id_t   generate_new_device_id( void );
-
 
150
 
-
 
151
static networking_globals_t networking_globals;
91
 
152
 
92
    argv[0] = fname;
153
DEVICE_MAP_IMPLEMENT( netifs, netif_t )
93
    argv[1] = NULL;
-
 
94
 
154
 
95
    res = task_spawn(fname, argv);
155
GENERIC_CHAR_MAP_IMPLEMENT( measured_strings, measured_string_t )
96
    if( res != 0 ){
-
 
97
        /* Success */
-
 
98
        sleep(1);
-
 
99
    }else return EINVAL;
-
 
100
 
156
 
101
    return EOK;
157
GENERIC_CHAR_MAP_IMPLEMENT( modules, module_t )
102
}
-
 
103
 
158
 
104
/** Initializes the module.
-
 
105
 */
-
 
106
int networking_initialize( void ){
159
int add_module( module_ref * module, modules_ref modules, const char * name, const char * filename, services_t service, task_id_t task_id ){
107
    ERROR_DECLARE;
160
    ERROR_DECLARE;
108
 
161
 
109
#ifdef NETWORKING_modular
-
 
110
    ERROR_PROPAGATE( spawn("/sbin/ip"));
-
 
111
//  ERROR_PROPAGATE( spawn("/sbin/arp"));
-
 
112
//  ERROR_PROPAGATE( spawn("/sbin/rarp"));
-
 
113
//  ERROR_PROPAGATE( spawn("/sbin/icmp"));
-
 
114
//  ERROR_PROPAGATE( spawn("/sbin/udp"));
-
 
115
    ERROR_PROPAGATE( spawn("/sbin/tcp"));
-
 
116
//  ERROR_PROPAGATE( spawn("/sbin/socket"));
-
 
117
#else
-
 
118
#ifdef NETWORKING_module
162
    module_ref  tmp_module;
119
    ipcarg_t phonehash;
-
 
120
 
163
 
121
    ERROR_PROPAGATE( REGISTER_ME( SERVICE_IP, & phonehash ));
164
    tmp_module = ( module_ref ) malloc( sizeof( module_t ));
122
    ERROR_PROPAGATE( ip_initialize());
165
    if( ! tmp_module ) return ENOMEM;
123
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ARP, & phonehash ));
-
 
124
//  ERROR_PROPAGATE( arp_initialize());
166
    tmp_module->task_id = task_id;
125
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_RARP, & phonehash ));
167
    tmp_module->phone = 0;
126
//  ERROR_PROPAGATE( rarp_initialize());
168
    tmp_module->usage = 0;
127
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ICMP, & phonehash ));
-
 
128
//  ERROR_PROPAGATE( icmp_initialize());
169
    tmp_module->name = name;
129
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_UDP, & phonehash ));
-
 
130
//  ERROR_PROPAGATE( udp_initialize());
170
    tmp_module->filename = filename;
131
    ERROR_PROPAGATE( REGISTER_ME( SERVICE_TCP, & phonehash ));
-
 
132
    ERROR_PROPAGATE( tcp_initialize());
171
    tmp_module->service = service;
133
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_SOCKET, & phonehash ));
172
    if( ERROR_OCCURED( modules_add( modules, tmp_module->name, tmp_module ))){
134
//  ERROR_PROPAGATE( socket_initialize());
173
        free( tmp_module );
135
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ETHERNET, & phonehash ));
-
 
136
//  ERROR_PROPAGATE( ethernet_initialize());
174
        return ERROR_CODE;
137
#endif
175
    }
138
#endif
176
    if( module ) * module = tmp_module;
139
    return EOK;
177
    return EOK;
140
}
178
}
141
 
179
 
142
/** Default thread for new connections.
-
 
143
 */
-
 
144
static void client_connection( ipc_callid_t iid, ipc_call_t * icall ){
180
static void client_connection( ipc_callid_t iid, ipc_call_t * icall ){
145
    ipc_callid_t callid;
181
    ipc_callid_t    callid;
146
    ipc_call_t call;
182
    ipc_call_t  call;
147
    ipcarg_t arg1, arg2, arg3;
183
    ipcarg_t    arg1, arg2, arg3;
148
    int res;
184
    int     res;
149
 
185
 
150
    /* Accept the connection */
186
    /* Accept the connection */
151
    ipc_answer_0( iid, EOK );
187
    ipc_answer_0( iid, EOK );
152
 
188
 
153
    while( true ){
189
    while( true ){
154
        callid = async_get_call( & call );
190
        callid = async_get_call( & call );
155
        arg1 = 0;
191
        arg1 = 0;
156
        arg2 = 0;
192
        arg2 = 0;
157
        arg3 = 0;
193
        arg3 = 0;
158
#ifdef NETWORKING_module
194
#ifdef NETWORKING_module
159
        if( IS_NET_IP_MESSAGE( call )){
195
        if( IS_NET_IL_MESSAGE( call ) || IS_NET_IP_MESSAGE( call )){
160
            res = ip_call( callid );
196
            res = ip_call( callid );
161
            if( res == EOK ){
197
            if( res == EOK ){
162
                res = ip_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
198
                res = ip_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
163
            }
199
            }
164
/*      }else if( IS_NET_ARP_MESSAGE( call )){
200
/*      }else if( IS_NET_ARP_MESSAGE( call )){
Line 189... Line 225...
189
/*      }else if( IS_NET_SOCKET_MESSAGE( call )){
225
/*      }else if( IS_NET_SOCKET_MESSAGE( call )){
190
            res = socket_call( callid );
226
            res = socket_call( callid );
191
            if( res == EOK ){
227
            if( res == EOK ){
192
                res = socket_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
228
                res = socket_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
193
            }
229
            }
194
*//*        }else if( IS_NET_ETHERNET_MESSAGE( call )){
230
*//*        }else if( IS_NET_LL_MESSAGE( call ) || IS_NET_ETHERNET_MESSAGE( call )){
195
            res = ethernet_call( callid );
231
            res = ethernet_call( callid );
196
            if( res == EOK ){
232
            if( res == EOK ){
197
                res = ethernet_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
233
                res = ethernet_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
198
            }
234
            }
199
*/      }else{
235
*/      }else{
Line 203... Line 239...
203
                res = networking_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
239
                res = networking_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
204
            }
240
            }
205
#ifdef NETWORKING_module
241
#ifdef NETWORKING_module
206
        }
242
        }
207
#endif
243
#endif
208
        ipc_answer_2( callid, EOK, arg1, arg2 );
244
        ipc_answer_2( callid, res, arg1, arg2 );
209
    }
245
    }
210
}
246
}
211
 
247
 
212
/** Starts the module.
-
 
213
 *  Parameters are ignored.
-
 
214
 */
-
 
215
int main( int argc, char * argv[] ){
248
int main( int argc, char * argv[] ){
216
 
249
 
217
    printf("networking : HelenOS Networking subsystem\n");
250
    printf("\nTask %d - Networking: HelenOS Networking subsystem\n", task_get_id());
218
 
251
 
219
    return start_service( SERVICE_NETWORKING, NULL, NULL, client_connection, networking_initialize );
252
    return start_service( SERVICE_NETWORKING, NULL, NULL, client_connection, networking_initialize );
220
}
253
}
221
 
254
 
-
 
255
int networking_call( ipc_callid_t callid ){
-
 
256
    return EOK;
-
 
257
}
-
 
258
 
-
 
259
int networking_initialize( void ){
-
 
260
    ERROR_DECLARE;
-
 
261
 
-
 
262
    task_id_t   task_id;
-
 
263
 
-
 
264
    netifs_initialize( & networking_globals.netifs );
-
 
265
    char_map_initialize( & networking_globals.netif_names );
-
 
266
    modules_initialize( & networking_globals.modules );
-
 
267
    measured_strings_initialize( & networking_globals.configuration );
-
 
268
 
-
 
269
    // run self tests
-
 
270
//  ERROR_PROPAGATE( self_test());
-
 
271
 
-
 
272
    ERROR_PROPAGATE( add_module( NULL, & networking_globals.modules, LO_NAME, LO_FILENAME, SERVICE_LO, 0 ));
-
 
273
    ERROR_PROPAGATE( add_module( NULL, & networking_globals.modules, DP8390_ISA_NAME, DP8390_ISA_FILENAME, SERVICE_DP8390_ISA, 0 ));
-
 
274
    ERROR_PROPAGATE( add_module( NULL, & networking_globals.modules, ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0 ));
-
 
275
 
-
 
276
#ifdef NETWORKING_modular
-
 
277
    task_id = spawn( "/sbin/ip" );
-
 
278
    if( ! task_id ) return EINVAL;
-
 
279
    ERROR_PROPAGATE( add_module( NULL, & networking_globals.modules, IP_NAME, IP_FILENAME, SERVICE_IP, task_id ));
-
 
280
//  if( ! spawn( "/sbin/udp" )) return EINVAL;
-
 
281
    if( ! spawn( "/sbin/tcp" )) return EINVAL;
-
 
282
//  if( ! spawn( "/sbin/socket" )) return EINVAL;
-
 
283
//  not always necesssary
-
 
284
//  if( ! spawn( "/sbin/arp" )) return EINVAL;
-
 
285
//  if( ! spawn( "/sbin/rarp" )) return EINVAL;
-
 
286
//  if( ! spawn( "/sbin/icmp" )) return EINVAL;
-
 
287
 
-
 
288
#else
-
 
289
#ifdef NETWORKING_module
-
 
290
    ipcarg_t    phonehash;
-
 
291
 
-
 
292
    ERROR_PROPAGATE( REGISTER_ME( SERVICE_IP, & phonehash ));
-
 
293
    ERROR_PROPAGATE( add_module( NULL, & networking_globals.modules, IP_NAME, IP_FILENAME, SERVICE_IP, task_get_id()));
-
 
294
    ERROR_PROPAGATE( ip_initialize());
-
 
295
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ARP, & phonehash ));
-
 
296
//  ERROR_PROPAGATE( arp_initialize());
-
 
297
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_RARP, & phonehash ));
-
 
298
//  ERROR_PROPAGATE( rarp_initialize());
-
 
299
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ICMP, & phonehash ));
-
 
300
//  ERROR_PROPAGATE( icmp_initialize());
-
 
301
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_UDP, & phonehash ));
-
 
302
//  ERROR_PROPAGATE( udp_initialize());
-
 
303
    ERROR_PROPAGATE( REGISTER_ME( SERVICE_TCP, & phonehash ));
-
 
304
    ERROR_PROPAGATE( tcp_initialize());
-
 
305
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_SOCKET, & phonehash ));
-
 
306
//  ERROR_PROPAGATE( socket_initialize());
-
 
307
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ETHERNET, & phonehash ));
-
 
308
//  ERROR_PROPAGATE( ethernet_initialize());
-
 
309
#endif
-
 
310
#endif
-
 
311
 
-
 
312
    return EOK;
-
 
313
}
-
 
314
 
-
 
315
int networking_message( ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 ){
-
 
316
    ERROR_DECLARE;
-
 
317
 
-
 
318
    measured_string_ref strings;
-
 
319
    char *          data;
-
 
320
    int         index;
-
 
321
    measured_string_ref setting;
-
 
322
    measured_strings_ref    configuration;
-
 
323
    netif_ref       netif;
-
 
324
 
-
 
325
//  printf( "\nNetworking message: %d\n", method );
-
 
326
    switch( method ){
-
 
327
//      case IPC_M_CONNECT_ME_TO:
-
 
328
        case IPC_M_PHONE_HUNGUP:
-
 
329
            return EOK;
-
 
330
        case NET_NETWORKING_DEVICE:
-
 
331
            // TODO configure, register
-
 
332
            // arg1 = netif id
-
 
333
            printf( "\nNetworking: new netif %d", arg1 );
-
 
334
            return EOK;
-
 
335
        case NET_NETWORKING_GET_DEVICE_CONFIGURATION:
-
 
336
            // arg1 = netif id
-
 
337
            // arg2 = count
-
 
338
            ERROR_PROPAGATE( measured_strings_receive( & strings, & data, arg2 ));
-
 
339
            netif = netifs_find( & networking_globals.netifs, arg1 );
-
 
340
            if( netif ){
-
 
341
                configuration = & netif->configuration;
-
 
342
            }else{
-
 
343
                configuration = NULL;
-
 
344
            }
-
 
345
            for( index = 0; index < arg2; ++ index ){
-
 
346
                setting = measured_strings_find( configuration, strings[ index ].value );
-
 
347
                if( ! setting ){
-
 
348
                    setting = measured_strings_find( & networking_globals.configuration, strings[ index ].value );
-
 
349
                }
-
 
350
                if( setting ){
-
 
351
                    strings[ index ].length = setting->length;
-
 
352
                    strings[ index ].value = setting->value;
-
 
353
                }else{
-
 
354
                    strings[ index ].length = 0;
-
 
355
                    strings[ index ].value = NULL;
-
 
356
                }
-
 
357
            }
-
 
358
            // strings should not contain received data anymore
-
 
359
            free( data );
-
 
360
            ERROR_CODE = measured_strings_reply( strings, arg2 );
-
 
361
            free( strings );
-
 
362
            return ERROR_CODE;
-
 
363
        case NET_NETWORKING_GET_CONFIGURATION:
-
 
364
            // arg1 = count
-
 
365
            ERROR_PROPAGATE( measured_strings_receive( & strings, & data, arg1 ));
-
 
366
            for( index = 0; index < arg1; ++ index ){
-
 
367
                setting = measured_strings_find( & networking_globals.configuration, strings[ index ].value );
-
 
368
                if( setting ){
-
 
369
                    strings[ index ].length = setting->length;
-
 
370
                    strings[ index ].value = setting->value;
-
 
371
                }else{
-
 
372
                    strings[ index ].length = 0;
-
 
373
                    strings[ index ].value = NULL;
-
 
374
                }
-
 
375
            }
-
 
376
            // strings should not contain received data anymore
-
 
377
            free( data );
-
 
378
            ERROR_CODE = measured_strings_reply( strings, arg1 );
-
 
379
            free( strings );
-
 
380
            return ERROR_CODE;
-
 
381
        case NET_NETWORKING_STARTUP:
-
 
382
            return startup();
-
 
383
    }
-
 
384
    return ENOTSUP;
-
 
385
}
-
 
386
 
-
 
387
/*
-
 
388
int parse_line( measured_strings_ref configuration, char * line ){
-
 
389
    ERROR_DECLARE;
-
 
390
 
-
 
391
    measured_string_ref setting;
-
 
392
    char *          name;
-
 
393
    char *          value;
-
 
394
 
-
 
395
    // from the beginning
-
 
396
    name = line;
-
 
397
    // skip spaces
-
 
398
    while( isspace( * name )) ++ name;
-
 
399
    // remember the name start
-
 
400
    value = name;
-
 
401
    // skip the name
-
 
402
    while( isalnum( * value ) || ( * value == '_' )){
-
 
403
        // make uppercase
-
 
404
//      * value = toupper( * value );
-
 
405
        ++ value;
-
 
406
    }
-
 
407
    if( * value == '=' ){
-
 
408
        // terminate the name
-
 
409
        * value = '\0';
-
 
410
    }else{
-
 
411
        // terminate the name
-
 
412
        * value = '\0';
-
 
413
        // skip until '='
-
 
414
        ++ value;
-
 
415
        while(( * value ) && ( * value != '=' )) ++ value;
-
 
416
        // not found?
-
 
417
        if( * value != '=' ) return EINVAL;
-
 
418
    }
-
 
419
    ++ value;
-
 
420
    // skip spaces
-
 
421
    while( isspace( * value )) ++ value;
-
 
422
    // create a bulk measured string till the end
-
 
423
    setting = measured_string_create_bulk( value, -1 );
-
 
424
    if( ! setting ) return ENOMEM;
-
 
425
    // add the configuration setting
-
 
426
    if( ERROR_OCCURED( measured_strings_add( configuration, name, setting ))){
-
 
427
        free( setting );
-
 
428
        return ERROR_CODE;
-
 
429
    }
-
 
430
    return EOK;
-
 
431
}
-
 
432
*/
-
 
433
 
-
 
434
int add_configuration( measured_strings_ref configuration, const char * name, const char * value ){
-
 
435
    ERROR_DECLARE;
-
 
436
 
-
 
437
    measured_string_ref setting;
-
 
438
 
-
 
439
    setting = measured_string_create_bulk( value, 0 );
-
 
440
    if( ! setting ) return ENOMEM;
-
 
441
    // add the configuration setting
-
 
442
    if( ERROR_OCCURED( measured_strings_add( configuration, name, setting ))){
-
 
443
        free( setting );
-
 
444
        return ERROR_CODE;
-
 
445
    }
-
 
446
    return EOK;
-
 
447
}
-
 
448
 
-
 
449
netif_device_id_t generate_new_device_id( void ){
-
 
450
    return netifs_count( & networking_globals.netifs ) + 1;
-
 
451
}
-
 
452
 
-
 
453
int read_configuration( void ){
-
 
454
    ERROR_DECLARE;
-
 
455
 
-
 
456
    netif_ref       netif;
-
 
457
    measured_string_ref setting;
-
 
458
    services_t      internet_service;
-
 
459
 
-
 
460
    // read general configuration
-
 
461
    ERROR_PROPAGATE( add_configuration( & networking_globals.configuration, "IPV", "4" ));
-
 
462
 
-
 
463
    // read network interfaces configuration
-
 
464
 
-
 
465
    // static loopback initialization
-
 
466
    printf( "\nloopback initialization" );
-
 
467
    netif = ( netif_ref ) malloc( sizeof( netif_t ));
-
 
468
    if( ! netif ) return ENOMEM;
-
 
469
    netif->id = generate_new_device_id();
-
 
470
    ERROR_PROPAGATE( measured_strings_initialize( & netif->configuration ));
-
 
471
    if( ERROR_OCCURED( add_configuration( & netif->configuration, "NAME", LO_NAME ))
-
 
472
        || ERROR_OCCURED( add_configuration( & netif->configuration, "NETIF", LO_NAME ))
-
 
473
        || ERROR_OCCURED( add_configuration( & netif->configuration, "IL", IP_NAME ))
-
 
474
        || ERROR_OCCURED( add_configuration( & netif->configuration, "IP_CONFIG", "STATIC" ))
-
 
475
        || ERROR_OCCURED( add_configuration( & netif->configuration, "IP_ADDR", "127.0.0.1" ))
-
 
476
        || ERROR_OCCURED( add_configuration( & netif->configuration, "NETMASK", "255.255.255.255" ))
-
 
477
        ){
-
 
478
        measured_strings_destroy( & netif->configuration );
-
 
479
        free( netif );
-
 
480
        return ERROR_CODE;
-
 
481
    }
-
 
482
    // mandatory name
-
 
483
    printf( "\n\tname" );
-
 
484
    setting = measured_strings_find( & netif->configuration, "NAME" );
-
 
485
    if( ! setting ){
-
 
486
        measured_strings_destroy( & netif->configuration );
-
 
487
        free( netif );
-
 
488
        return EINVAL;
-
 
489
    }
-
 
490
    netif->name = setting->value;
-
 
491
    printf( " %s OK", netif->name );
-
 
492
    // mandatory netif
-
 
493
    printf( "\n\tnetif" );
-
 
494
    setting = measured_strings_find( & netif->configuration, "NETIF" );
-
 
495
    if( ! setting ){
-
 
496
        printf( " unknown" );
-
 
497
        measured_strings_destroy( & netif->configuration );
-
 
498
        free( netif );
-
 
499
        return EINVAL;
-
 
500
    }
-
 
501
//  printf( " find %s in %d?", setting->value, modules_count( & networking_globals.modules ));
-
 
502
    netif->driver_module = modules_find( & networking_globals.modules, setting->value );
-
 
503
    if( ! netif->driver_module ){
-
 
504
        printf( " not found" );
-
 
505
        // TODO register the unknown one
-
 
506
        measured_strings_destroy( & netif->configuration );
-
 
507
        free( netif );
-
 
508
        return EINVAL;
-
 
509
    }
-
 
510
    printf( " found" );
-
 
511
    if( ! netif->driver_module->task_id ){
-
 
512
        netif->driver_module->task_id = spawn( netif->driver_module->filename );
-
 
513
        if( ! netif->driver_module->task_id ){
-
 
514
            measured_strings_destroy( & netif->configuration );
-
 
515
            free( netif );
-
 
516
            return EINVAL;
-
 
517
        }
-
 
518
    }
-
 
519
    if( ! netif->driver_module->phone ){
-
 
520
        printf( " connect?" );
-
 
521
        netif->driver_module->phone = connect_to_service( netif->driver_module->service );
-
 
522
    }
-
 
523
    printf( " connected" );
-
 
524
    if( ERROR_OCCURED( ipc_call_sync_1_0( netif->driver_module->phone, NET_NETIF_PROBE, netif->id ))){
-
 
525
        measured_strings_destroy( & netif->configuration );
-
 
526
        free( netif );
-
 
527
        return ERROR_CODE;
-
 
528
    }
-
 
529
    ++ netif->driver_module->usage;
-
 
530
    printf( " OK" );
-
 
531
    // optional link layer
-
 
532
    printf( "\n\tlink layer" );
-
 
533
    setting = measured_strings_find( & netif->configuration, "LL" );
-
 
534
    if( setting ){
-
 
535
        netif->link_layer_module = modules_find( & networking_globals.modules, setting->value );
-
 
536
        if( ! netif->link_layer_module ){
-
 
537
            // TODO register the unknown one
-
 
538
            -- netif->driver_module->usage;
-
 
539
            measured_strings_destroy( & netif->configuration );
-
 
540
            free( netif );
-
 
541
            return EINVAL;
-
 
542
        }
-
 
543
        if( ! netif->link_layer_module->task_id ){
-
 
544
            netif->link_layer_module->task_id = spawn( netif->link_layer_module->filename );
-
 
545
            if( ! netif->link_layer_module->task_id ){
-
 
546
                -- netif->driver_module->usage;
-
 
547
                measured_strings_destroy( & netif->configuration );
-
 
548
                free( netif );
-
 
549
                return EINVAL;
-
 
550
            }
-
 
551
        }
-
 
552
        if( ! netif->link_layer_module->phone ){
-
 
553
            netif->link_layer_module->phone = connect_to_service( netif->link_layer_module->service );
-
 
554
        }
-
 
555
        if( ERROR_OCCURED( ipc_call_sync_2_0( netif->link_layer_module->phone, NET_LL_DEVICE, netif->id, netif->driver_module->service ))){
-
 
556
            -- netif->driver_module->usage;
-
 
557
            measured_strings_destroy( & netif->configuration );
-
 
558
            free( netif );
-
 
559
            return ERROR_CODE;
-
 
560
        }
-
 
561
        ++ netif->link_layer_module->usage;
-
 
562
        internet_service = netif->link_layer_module->service;
-
 
563
        printf( " OK" );
-
 
564
    }else{
-
 
565
        internet_service = netif->driver_module->service;
-
 
566
        printf( " none" );
-
 
567
    }
-
 
568
    // mandatory internet layer
-
 
569
    printf( "\n\tinternet layer" );
-
 
570
    setting = measured_strings_find( & netif->configuration, "IL" );
-
 
571
    if( ! setting ){
-
 
572
        -- netif->driver_module->usage;
-
 
573
        -- netif->link_layer_module->usage;
-
 
574
        measured_strings_destroy( & netif->configuration );
-
 
575
        free( netif );
-
 
576
        return EINVAL;
-
 
577
    }
-
 
578
    printf( " set %s", setting->value );
-
 
579
    netif->internet_layer_module = modules_find( & networking_globals.modules, setting->value );
-
 
580
    if( ! netif->internet_layer_module ){
-
 
581
        // TODO register the unknown one
-
 
582
        -- netif->driver_module->usage;
-
 
583
        -- netif->link_layer_module->usage;
-
 
584
        measured_strings_destroy( & netif->configuration );
-
 
585
        free( netif );
-
 
586
        return EINVAL;
-
 
587
    }
-
 
588
    printf( " found" );
-
 
589
    if( ! netif->internet_layer_module->task_id ){
-
 
590
        netif->internet_layer_module->task_id = spawn( netif->internet_layer_module->filename );
-
 
591
        if( ! netif->internet_layer_module->task_id ){
-
 
592
            -- netif->driver_module->usage;
-
 
593
            -- netif->link_layer_module->usage;
-
 
594
            measured_strings_destroy( & netif->configuration );
-
 
595
            free( netif );
-
 
596
            return EINVAL;
-
 
597
        }
-
 
598
    }
-
 
599
    if( ! netif->internet_layer_module->phone ){
-
 
600
        printf( " connect" );
-
 
601
        netif->internet_layer_module->phone = connect_to_service( netif->internet_layer_module->service );
-
 
602
    }
-
 
603
    if( ERROR_OCCURED( ipc_call_sync_2_0( netif->internet_layer_module->phone, NET_IL_DEVICE, netif->id, internet_service ))){
-
 
604
        measured_strings_destroy( & netif->configuration );
-
 
605
        free( netif );
-
 
606
        return ERROR_CODE;
-
 
607
    }
-
 
608
    ++ netif->internet_layer_module->usage;
-
 
609
    printf( " OK" );
-
 
610
    if( ERROR_OCCURED( netifs_add( & networking_globals.netifs, netif->id, netif ))){
-
 
611
        free( netif );
-
 
612
        return ERROR_CODE;
-
 
613
    }
-
 
614
    printf( "\nloopback OK" );
-
 
615
    // end of static loopback initialization
-
 
616
    return EOK;
-
 
617
}
-
 
618
 
-
 
619
task_id_t spawn( const char * fname ){
-
 
620
    const char  * argv[ 2 ];
-
 
621
    task_id_t   res;
-
 
622
 
-
 
623
//  printf( "Spawning %s\n", fname );
-
 
624
    argv[ 0 ] = fname;
-
 
625
    argv[ 1 ] = NULL;
-
 
626
    res = task_spawn( fname, argv );
-
 
627
    if( res != 0 ){
-
 
628
        /* Success */
-
 
629
        usleep( 50000 );
-
 
630
    }
-
 
631
    return res;
-
 
632
}
-
 
633
 
-
 
634
int startup( void ){
-
 
635
    ERROR_DECLARE;
-
 
636
 
-
 
637
    // read configuration files
-
 
638
    if( ERROR_OCCURED( read_configuration())) return ERROR_CODE;
-
 
639
 
-
 
640
    // start network interfaces and needed modules
-
 
641
//  start_device( "/sbin/lo", "/sbin/dummy_link_layer" );
-
 
642
    return EOK;
-
 
643
}
-
 
644
 
222
/** @}
645
/** @}
223
 */
646
 */