Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/net/net.c

    ree2fa30a r00d7e1b  
    11/*
    22 * Copyright (c) 2009 Lukas Mejdrech
     3 * Copyright (c) 2011 Radim Vansa
    34 * All rights reserved.
    45 *
     
    3132 */
    3233
    33 /** @file
    34  * Networking subsystem central module implementation.
    35  *
    36  */
    37 
     34#include <assert.h>
    3835#include <async.h>
    3936#include <ctype.h>
    4037#include <ddi.h>
    4138#include <errno.h>
     39#include <str_error.h>
    4240#include <malloc.h>
    4341#include <stdio.h>
    4442#include <str.h>
     43#include <devman.h>
    4544#include <str_error.h>
    4645#include <ns.h>
     
    4948#include <ipc/net_net.h>
    5049#include <ipc/il.h>
     50#include <ipc/ip.h>
    5151#include <ipc/nil.h>
    52 #include <net/modules.h>
    5352#include <net/packet.h>
    5453#include <net/device.h>
     
    5756#include <adt/measured_strings.h>
    5857#include <adt/module_map.h>
    59 #include <netif_remote.h>
    6058#include <nil_remote.h>
    6159#include <net_interface.h>
    6260#include <ip_interface.h>
     61#include <device/nic.h>
     62#include <dirent.h>
     63#include <fcntl.h>
     64#include <cfg.h>
    6365#include "net.h"
    64 
    65 /** Networking module name. */
    66 #define NAME  "net"
    67 
    68 /** File read buffer size. */
    69 #define BUFFER_SIZE  256
     66#include "packet_server.h"
     67
     68#define MAX_PATH_LENGTH  1024
    7069
    7170/** Networking module global data. */
     
    7473GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t);
    7574DEVICE_MAP_IMPLEMENT(netifs, netif_t);
    76 
    77 static int startup(void);
    7875
    7976/** Add the configured setting to the configuration map.
     
    8784 *
    8885 */
    89 int add_configuration(measured_strings_t *configuration, const uint8_t *name,
    90     const uint8_t *value)
     86static int add_configuration(measured_strings_t *configuration,
     87    const uint8_t *name, const uint8_t *value)
    9188{
    9289        int rc;
     
    109106/** Generate new system-unique device identifier.
    110107 *
    111  * @return              The system-unique devic identifier.
    112  */
    113 static device_id_t generate_new_device_id(void)
     108 * @return The system-unique devic identifier.
     109 *
     110 */
     111static nic_device_id_t generate_new_device_id(void)
    114112{
    115113        return device_assign_devno();
    116 }
    117 
    118 static int parse_line(measured_strings_t *configuration, uint8_t *line)
    119 {
    120         int rc;
    121        
    122         /* From the beginning */
    123         uint8_t *name = line;
    124        
    125         /* Skip comments and blank lines */
    126         if ((*name == '#') || (*name == '\0'))
    127                 return EOK;
    128        
    129         /* Skip spaces */
    130         while (isspace(*name))
    131                 name++;
    132        
    133         /* Remember the name start */
    134         uint8_t *value = name;
    135        
    136         /* Skip the name */
    137         while (isalnum(*value) || (*value == '_'))
    138                 value++;
    139        
    140         if (*value == '=') {
    141                 /* Terminate the name */
    142                 *value = '\0';
    143         } else {
    144                 /* Terminate the name */
    145                 *value = '\0';
    146                
    147                 /* Skip until '=' */
    148                 value++;
    149                 while ((*value) && (*value != '='))
    150                         value++;
    151                
    152                 /* Not found? */
    153                 if (*value != '=')
    154                         return EINVAL;
    155         }
    156        
    157         value++;
    158        
    159         /* Skip spaces */
    160         while (isspace(*value))
    161                 value++;
    162        
    163         /* Create a bulk measured string till the end */
    164         measured_string_t *setting =
    165             measured_string_create_bulk(value, 0);
    166         if (!setting)
    167                 return ENOMEM;
    168        
    169         /* Add the configuration setting */
    170         rc = measured_strings_add(configuration, name, 0, setting);
    171         if (rc != EOK) {
    172                 free(setting);
    173                 return rc;
    174         }
    175        
    176         return EOK;
    177114}
    178115
     
    182119        printf("%s: Reading configuration file %s/%s\n", NAME, directory, filename);
    183120       
    184         /* Construct the full filename */
    185         char fname[BUFFER_SIZE];
    186         if (snprintf(fname, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE)
    187                 return EOVERFLOW;
    188        
    189         /* Open the file */
    190         FILE *cfg = fopen(fname, "r");
    191         if (!cfg)
     121        cfg_file_t cfg;
     122        int rc = cfg_load_path(directory, filename, &cfg);
     123        if (rc != EOK)
     124                return rc;
     125       
     126        if (cfg_anonymous(&cfg) == NULL) {
     127                cfg_unload(&cfg);
    192128                return ENOENT;
    193        
    194         /*
    195          * Read the configuration line by line
    196          * until an error or the end of file
    197          */
    198         unsigned int line_number = 0;
    199         size_t index = 0;
    200         uint8_t line[BUFFER_SIZE];
    201        
    202         while (!ferror(cfg) && !feof(cfg)) {
    203                 int read = fgetc(cfg);
    204                 if ((read > 0) && (read != '\n') && (read != '\r')) {
    205                         if (index >= BUFFER_SIZE) {
    206                                 line[BUFFER_SIZE - 1] = '\0';
    207                                 fprintf(stderr, "%s: Configuration line %u too "
    208                                     "long: %s\n", NAME, line_number, (char *) line);
    209                                
    210                                 /* No space left in the line buffer */
    211                                 return EOVERFLOW;
    212                         }
    213                         /* Append the character */
    214                         line[index] = (uint8_t) read;
    215                         index++;
    216                 } else {
    217                         /* On error or new line */
    218                         line[index] = '\0';
    219                         line_number++;
    220                         if (parse_line(configuration, line) != EOK) {
    221                                 fprintf(stderr, "%s: Configuration error on "
    222                                     "line %u: %s\n", NAME, line_number, (char *) line);
    223                         }
    224                        
    225                         index = 0;
     129        }
     130       
     131        cfg_section_foreach(cfg_anonymous(&cfg), link) {
     132                const cfg_entry_t *entry = cfg_entry_instance(link);
     133               
     134                rc = add_configuration(configuration,
     135                    (uint8_t *) entry->key, (uint8_t *) entry->value);
     136                if (rc != EOK) {
     137                        cfg_unload(&cfg);
     138                        return rc;
    226139                }
    227140        }
    228141       
    229         fclose(cfg);
     142        cfg_unload(&cfg);
    230143        return EOK;
    231144}
     
    255168        return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE,
    256169            &net_globals.configuration);
    257 }
    258 
    259 /** Initialize the networking module.
    260  *
    261  * @param[in] client_connection The client connection processing
    262  *                              function. The module skeleton propagates
    263  *                              its own one.
    264  *
    265  * @return EOK on success.
    266  * @return ENOMEM if there is not enough memory left.
    267  *
    268  */
    269 static int net_initialize(async_client_conn_t client_connection)
    270 {
    271         int rc;
    272        
    273         netifs_initialize(&net_globals.netifs);
    274         char_map_initialize(&net_globals.netif_names);
    275         modules_initialize(&net_globals.modules);
    276         measured_strings_initialize(&net_globals.configuration);
    277        
    278         /* TODO: dynamic configuration */
    279         rc = read_configuration();
    280         if (rc != EOK)
    281                 return rc;
    282        
    283         rc = add_module(NULL, &net_globals.modules, (uint8_t *) LO_NAME,
    284             (uint8_t *) LO_FILENAME, SERVICE_LO, 0, connect_to_service);
    285         if (rc != EOK)
    286                 return rc;
    287        
    288         rc = add_module(NULL, &net_globals.modules, (uint8_t *) NE2000_NAME,
    289             (uint8_t *) NE2000_FILENAME, SERVICE_NE2000, 0, connect_to_service);
    290         if (rc != EOK)
    291                 return rc;
    292        
    293         rc = add_module(NULL, &net_globals.modules, (uint8_t *) ETHERNET_NAME,
    294             (uint8_t *) ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service);
    295         if (rc != EOK)
    296                 return rc;
    297        
    298         rc = add_module(NULL, &net_globals.modules, (uint8_t *) NILDUMMY_NAME,
    299             (uint8_t *) NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service);
    300         if (rc != EOK)
    301                 return rc;
    302        
    303         /* Build specific initialization */
    304         return net_initialize_build(client_connection);
    305 }
    306 
    307 /** Start the networking module.
    308  *
    309  * Initializes the client connection serving function,
    310  * initializes the module, registers the module service
    311  * and starts the async manager, processing IPC messages
    312  * in an infinite loop.
    313  *
    314  * @param[in] client_connection The client connection
    315  *                              processing function. The
    316  *                              module skeleton propagates
    317  *                              its own one.
    318  *
    319  * @return EOK on successful module termination.
    320  * @return Other error codes as defined for the net_initialize() function.
    321  * @return Other error codes as defined for the REGISTER_ME() macro function.
    322  *
    323  */
    324 static int net_module_start(async_client_conn_t client_connection)
    325 {
    326         int rc;
    327        
    328         async_set_client_connection(client_connection);
    329         rc = pm_init();
    330         if (rc != EOK)
    331                 return rc;
    332        
    333         rc = net_initialize(client_connection);
    334         if (rc != EOK)
    335                 goto out;
    336        
    337         rc = service_register(SERVICE_NETWORKING);
    338         if (rc != EOK)
    339                 goto out;
    340        
    341         rc = startup();
    342         if (rc != EOK)
    343                 goto out;
    344        
    345         task_retval(0);
    346         async_manager();
    347 
    348 out:
    349         pm_destroy();
    350         return rc;
    351170}
    352171
     
    364183 */
    365184static int net_get_conf(measured_strings_t *netif_conf,
    366     measured_string_t *configuration, size_t count, uint8_t **data)
    367 {
    368         if (data)
    369                 *data = NULL;
     185    measured_string_t *configuration, size_t count)
     186{
     187        if ((!configuration) || (count <= 0))
     188                        return EINVAL;
    370189       
    371190        size_t index;
     
    389208}
    390209
    391 static int net_get_conf_req_local(measured_string_t **configuration,
    392     size_t count, uint8_t **data)
    393 {
    394         if (!configuration || (count <= 0))
    395                 return EINVAL;
    396        
    397         return net_get_conf(NULL, *configuration, count, data);
    398 }
    399 
    400 static int net_get_device_conf_req_local(device_id_t device_id,
    401     measured_string_t **configuration, size_t count, uint8_t **data)
    402 {
    403         if ((!configuration) || (count == 0))
    404                 return EINVAL;
    405 
     210static int net_get_device_conf(nic_device_id_t device_id,
     211    measured_string_t *configuration, size_t count)
     212{
    406213        netif_t *netif = netifs_find(&net_globals.netifs, device_id);
    407214        if (netif)
    408                 return net_get_conf(&netif->configuration, *configuration, count, data);
     215                return net_get_conf(&netif->configuration, configuration, count);
    409216        else
    410                 return net_get_conf(NULL, *configuration, count, data);
    411 }
    412 
    413 void net_free_settings(measured_string_t *settings, uint8_t *data)
    414 {
     217                return net_get_conf(NULL, configuration, count);
     218}
     219
     220static int net_get_devices(measured_string_t **devices, size_t *dev_count)
     221{
     222        if (!devices)
     223                return EBADMEM;
     224       
     225        size_t max_count = netifs_count(&net_globals.netifs);
     226        *devices = malloc(max_count * sizeof(measured_string_t));
     227        if (*devices == NULL)
     228                return ENOMEM;
     229       
     230        size_t count = 0;
     231        for (size_t i = 0; i < max_count; i++) {
     232                netif_t *item = netifs_get_index(&net_globals.netifs, i);
     233                if (item->sess != NULL) {
     234                        /*
     235                         * Use format "device_id:device_name"
     236                         * FIXME: This typecasting looks really ugly
     237                         */
     238                        (*devices)[count].length = asprintf(
     239                            (char **) &((*devices)[count].value),
     240                            NIC_DEVICE_PRINT_FMT ":%s", item->id,
     241                            (const char *) item->name);
     242                        count++;
     243                }
     244        }
     245       
     246        *dev_count = (size_t) count;
     247        return EOK;
     248}
     249
     250static int net_get_devices_count()
     251{
     252        size_t max_count = netifs_count(&net_globals.netifs);
     253       
     254        size_t count = 0;
     255        for (size_t i = 0; i < max_count; i++) {
     256                netif_t *item = netifs_get_index(&net_globals.netifs, i);
     257                if (item->sess != NULL)
     258                        count++;
     259        }
     260       
     261        return count;
     262}
     263
     264static void net_free_devices(measured_string_t *devices, size_t count)
     265{
     266        size_t i;
     267        for (i = 0; i < count; ++i)
     268                free(devices[i].value);
     269       
     270        free(devices);
    415271}
    416272
     
    431287 *
    432288 */
    433 static int start_device(netif_t *netif)
    434 {
    435         int rc;
    436        
    437         /* Mandatory netif */
    438         measured_string_t *setting =
    439             measured_strings_find(&netif->configuration, (uint8_t *) CONF_NETIF, 0);
    440        
    441         netif->driver = get_running_module(&net_globals.modules, setting->value);
    442         if (!netif->driver) {
    443                 fprintf(stderr, "%s: Failed to start network interface driver '%s'\n",
    444                     NAME, setting->value);
    445                 return EINVAL;
     289static int init_device(netif_t *netif, devman_handle_t handle)
     290{
     291        printf("%s: Initializing device '%s'\n", NAME, netif->name);
     292       
     293        netif->handle = handle;
     294        netif->sess = devman_device_connect(EXCHANGE_SERIALIZE, netif->handle,
     295            IPC_FLAG_BLOCKING);
     296        if (netif->sess == NULL) {
     297                printf("%s: Unable to connect to device\n", NAME);
     298                return EREFUSED;
    446299        }
    447300       
    448301        /* Optional network interface layer */
    449         setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_NIL, 0);
     302        measured_string_t *setting = measured_strings_find(&netif->configuration,
     303            (uint8_t *) CONF_NIL, 0);
    450304        if (setting) {
    451                 netif->nil = get_running_module(&net_globals.modules, setting->value);
     305                netif->nil = get_running_module(&net_globals.modules,
     306                    setting->value);
    452307                if (!netif->nil) {
    453                         fprintf(stderr, "%s: Failed to start network interface layer '%s'\n",
     308                        printf("%s: Unable to connect to network interface layer '%s'\n",
    454309                            NAME, setting->value);
    455310                        return EINVAL;
     
    459314       
    460315        /* Mandatory internet layer */
    461         setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IL, 0);
    462         netif->il = get_running_module(&net_globals.modules, setting->value);
     316        setting = measured_strings_find(&netif->configuration,
     317            (uint8_t *) CONF_IL, 0);
     318        netif->il = get_running_module(&net_globals.modules,
     319            setting->value);
    463320        if (!netif->il) {
    464                 fprintf(stderr, "%s: Failed to start internet layer '%s'\n",
     321                printf("%s: Unable to connect to internet layer '%s'\n",
    465322                    NAME, setting->value);
    466323                return EINVAL;
    467324        }
    468325       
    469         /* Hardware configuration */
    470         setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IRQ, 0);
    471         int irq = setting ? strtol((char *) setting->value, NULL, 10) : 0;
    472        
    473         setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IO, 0);
    474         uintptr_t io = setting ? strtol((char *) setting->value, NULL, 16) : 0;
    475        
    476         rc = netif_probe_req(netif->driver->sess, netif->id, irq, (void *) io);
    477         if (rc != EOK)
    478                 return rc;
    479        
    480326        /* Network interface layer startup */
    481         services_t internet_service;
     327        int rc;
     328        services_t nil_service;
    482329        if (netif->nil) {
    483                 setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_MTU, 0);
     330                setting = measured_strings_find(&netif->configuration,
     331                    (uint8_t *) CONF_MTU, 0);
    484332                if (!setting)
    485333                        setting = measured_strings_find(&net_globals.configuration,
    486334                            (uint8_t *) CONF_MTU, 0);
    487335               
    488                 int mtu = setting ? strtol((char *) setting->value, NULL, 10) : 0;
    489                 rc = nil_device_req(netif->nil->sess, netif->id, mtu,
    490                     netif->driver->service);
     336                int mtu = setting ?
     337                    strtol((const char *) setting->value, NULL, 10) : 0;
     338                rc = nil_device_req(netif->nil->sess, netif->id,
     339                    netif->handle, mtu);
     340                if (rc != EOK) {
     341                        printf("%s: Unable to start network interface layer\n",
     342                            NAME);
     343                        return rc;
     344                }
     345               
     346                nil_service = netif->nil->service;
     347        } else
     348                nil_service = -1;
     349       
     350        /* Inter-network layer startup */
     351        switch (netif->il->service) {
     352        case SERVICE_IP:
     353                rc = ip_device_req(netif->il->sess, netif->id, nil_service);
     354                if (rc != EOK) {
     355                        printf("%s: Unable to start internet layer\n", NAME);
     356                        return rc;
     357                }
     358               
     359                break;
     360        default:
     361                return ENOENT;
     362        }
     363       
     364        printf("%s: Activating device '%s'\n", NAME, netif->name);
     365        return nic_set_state(netif->sess, NIC_STATE_ACTIVE);
     366}
     367
     368static int net_port_ready(devman_handle_t handle)
     369{
     370        char hwpath[MAX_PATH_LENGTH];
     371        int rc = devman_fun_get_path(handle, hwpath, MAX_PATH_LENGTH);
     372        if (rc != EOK)
     373                return EINVAL;
     374       
     375        int index = char_map_find(&net_globals.netif_hwpaths,
     376            (uint8_t *) hwpath, 0);
     377        if (index == CHAR_MAP_NULL)
     378                return ENOENT;
     379       
     380        netif_t *netif = netifs_get_index(&net_globals.netifs, index);
     381        if (netif == NULL)
     382                return ENOENT;
     383       
     384        rc = init_device(netif, handle);
     385        if (rc != EOK)
     386                return rc;
     387       
     388        /* Increment module usage */
     389        if (netif->nil)
     390                netif->nil->usage++;
     391       
     392        netif->il->usage++;
     393       
     394        return EOK;
     395}
     396
     397static int net_driver_ready_local(devman_handle_t handle)
     398{
     399        devman_handle_t *funs;
     400        size_t count;
     401        int rc = devman_dev_get_functions(handle, &funs, &count);
     402        if (rc != EOK)
     403                return rc;
     404       
     405        for (size_t i = 0; i < count; i++) {
     406                rc = net_port_ready(funs[i]);
    491407                if (rc != EOK)
    492408                        return rc;
    493                
    494                 internet_service = netif->nil->service;
    495         } else
    496                 internet_service = netif->driver->service;
    497        
    498         /* Inter-network layer startup */
    499         rc = ip_device_req(netif->il->sess, netif->id, internet_service);
    500         if (rc != EOK)
    501                 return rc;
    502        
    503         return netif_start_req(netif->driver->sess, netif->id);
    504 }
    505 
    506 /** Read the configuration and start all network interfaces.
    507  *
    508  * @return EOK on success.
    509  * @return EXDEV if there is no available system-unique device identifier.
    510  * @return EINVAL if any of the network interface names are not configured.
    511  * @return ENOMEM if there is not enough memory left.
    512  * @return Other error codes as defined for the read_configuration()
    513  *         function.
    514  * @return Other error codes as defined for the read_netif_configuration()
    515  *         function.
    516  * @return Other error codes as defined for the start_device() function.
    517  *
    518  */
    519 static int startup(void)
    520 {
    521         const char *conf_files[] = {
    522                 "lo",
    523                 "ne2k"
    524         };
    525         size_t count = sizeof(conf_files) / sizeof(char *);
    526         int rc;
    527        
    528         size_t i;
    529         for (i = 0; i < count; i++) {
    530                 netif_t *netif = (netif_t *) malloc(sizeof(netif_t));
    531                 if (!netif)
    532                         return ENOMEM;
    533                
    534                 netif->id = generate_new_device_id();
    535                 if (!netif->id)
    536                         return EXDEV;
    537                
    538                 rc = measured_strings_initialize(&netif->configuration);
    539                 if (rc != EOK)
    540                         return rc;
    541                
    542                 /* Read configuration files */
    543                 rc = read_netif_configuration(conf_files[i], netif);
    544                 if (rc != EOK) {
    545                         measured_strings_destroy(&netif->configuration, free);
    546                         free(netif);
    547                         return rc;
    548                 }
    549                
    550                 /* Mandatory name */
    551                 measured_string_t *setting =
    552                     measured_strings_find(&netif->configuration, (uint8_t *) CONF_NAME, 0);
    553                 if (!setting) {
    554                         fprintf(stderr, "%s: Network interface name is missing\n", NAME);
    555                         measured_strings_destroy(&netif->configuration, free);
    556                         free(netif);
    557                         return EINVAL;
    558                 }
    559                 netif->name = setting->value;
    560                
    561                 /* Add to the netifs map */
    562                 int index = netifs_add(&net_globals.netifs, netif->id, netif);
    563                 if (index < 0) {
    564                         measured_strings_destroy(&netif->configuration, free);
    565                         free(netif);
    566                         return index;
    567                 }
    568                
    569                 /*
    570                  * Add to the netif names map and start network interfaces
    571                  * and needed modules.
    572                  */
    573                 rc = char_map_add(&net_globals.netif_names, netif->name, 0,
    574                     index);
    575                 if (rc != EOK) {
    576                         measured_strings_destroy(&netif->configuration, free);
    577                         netifs_exclude_index(&net_globals.netifs, index, free);
    578                         return rc;
    579                 }
    580                
    581                 rc = start_device(netif);
    582                 if (rc != EOK) {
    583                         printf("%s: Ignoring failed interface %s (%s)\n", NAME,
    584                             netif->name, str_error(rc));
    585                         measured_strings_destroy(&netif->configuration, free);
    586                         netifs_exclude_index(&net_globals.netifs, index, free);
    587                         continue;
    588                 }
    589                
    590                 /* Increment modules' usage */
    591                 netif->driver->usage++;
    592                 if (netif->nil)
    593                         netif->nil->usage++;
    594                 netif->il->usage++;
    595                
    596                 printf("%s: Network interface started (name: %s, id: %d, driver: %s, "
    597                     "nil: %s, il: %s)\n", NAME, netif->name, netif->id,
    598                     netif->driver->name, netif->nil ? (char *) netif->nil->name : "[none]",
    599                     netif->il->name);
    600409        }
    601410       
     
    618427 *
    619428 */
    620 int net_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    621     size_t *answer_count)
     429static int net_message(ipc_callid_t callid, ipc_call_t *call,
     430    ipc_call_t *answer, size_t *answer_count)
    622431{
    623432        measured_string_t *strings;
    624433        uint8_t *data;
    625434        int rc;
     435        size_t count;
    626436       
    627437        *answer_count = 0;
     
    636446                if (rc != EOK)
    637447                        return rc;
    638                 net_get_device_conf_req_local(IPC_GET_DEVICE(*call), &strings,
    639                     IPC_GET_COUNT(*call), NULL);
    640                
    641                 /* Strings should not contain received data anymore */
    642                 free(data);
     448               
     449                net_get_device_conf(IPC_GET_DEVICE(*call), strings,
     450                    IPC_GET_COUNT(*call));
    643451               
    644452                rc = measured_strings_reply(strings, IPC_GET_COUNT(*call));
    645453                free(strings);
     454                free(data);
    646455                return rc;
    647456        case NET_NET_GET_CONF:
     
    650459                if (rc != EOK)
    651460                        return rc;
    652                 net_get_conf_req_local(&strings, IPC_GET_COUNT(*call), NULL);
    653                
    654                 /* Strings should not contain received data anymore */
    655                 free(data);
     461               
     462                net_get_conf(NULL, strings, IPC_GET_COUNT(*call));
    656463               
    657464                rc = measured_strings_reply(strings, IPC_GET_COUNT(*call));
    658465                free(strings);
    659                 return rc;
    660         case NET_NET_STARTUP:
    661                 return startup();
    662         }
    663        
    664         return ENOTSUP;
     466                free(data);
     467                return rc;
     468        case NET_NET_GET_DEVICES_COUNT:
     469                count = (size_t) net_get_devices_count();
     470                IPC_SET_ARG1(*answer, count);
     471                *answer_count = 1;
     472                return EOK;
     473        case NET_NET_GET_DEVICES:
     474                rc = net_get_devices(&strings, &count);
     475                if (rc != EOK)
     476                        return rc;
     477               
     478                rc = measured_strings_reply(strings, count);
     479                net_free_devices(strings, count);
     480                return rc;
     481        case NET_NET_DRIVER_READY:
     482                rc = net_driver_ready_local(IPC_GET_ARG1(*call));
     483                *answer_count = 0;
     484                return rc;
     485        default:
     486                return ENOTSUP;
     487        }
    665488}
    666489
     
    684507                /* Clear the answer structure */
    685508                ipc_call_t answer;
    686                 size_t answer_count;
    687                 refresh_answer(&answer, &answer_count);
     509                size_t count;
     510                refresh_answer(&answer, &count);
    688511               
    689512                /* Fetch the next message */
     
    692515               
    693516                /* Process the message */
    694                 int res = net_module_message(callid, &call, &answer, &answer_count);
     517                int res;
     518                if (IS_NET_PACKET_MESSAGE(call))
     519                        res = packet_server_message(callid, &call, &answer, &count);
     520                else
     521                        res = net_message(callid, &call, &answer, &count);
    695522               
    696523                /* End if told to either by the message or the processing result */
     
    699526               
    700527                /* Answer the message */
    701                 answer_call(callid, res, &answer, answer_count);
     528                answer_call(callid, res, &answer, count);
    702529        }
    703530}
     
    705532int main(int argc, char *argv[])
    706533{
    707         return net_module_start(net_client_connection);
     534        netifs_initialize(&net_globals.netifs);
     535        char_map_initialize(&net_globals.netif_hwpaths);
     536        modules_initialize(&net_globals.modules);
     537        measured_strings_initialize(&net_globals.configuration);
     538        async_set_client_connection(net_client_connection);
     539       
     540        int rc = pm_init();
     541        if (rc != EOK) {
     542                printf("%s: Unable to initialize packet management\n", NAME);
     543                return rc;
     544        }
     545       
     546        rc = packet_server_init();
     547        if (rc != EOK) {
     548                printf("%s: Unable to initialize packet server\n", NAME);
     549                pm_destroy();
     550                return rc;
     551        }
     552       
     553        rc = read_configuration();
     554        if (rc != EOK) {
     555                printf("%s: Error reading configuration\n", NAME);
     556                pm_destroy();
     557                return rc;
     558        }
     559       
     560        DIR *config_dir = opendir(CONF_DIR);
     561        if (config_dir != NULL) {
     562                struct dirent *dir_entry;
     563                while ((dir_entry = readdir(config_dir))) {
     564                        /* Ignore files without the CONF_EXT extension */
     565                        if ((str_size(dir_entry->d_name) < str_size(CONF_EXT)) ||
     566                            (str_cmp(dir_entry->d_name + str_size(dir_entry->d_name) -
     567                            str_size(CONF_EXT), CONF_EXT) != 0))
     568                                continue;
     569                       
     570                       
     571                        netif_t *netif = (netif_t *) malloc(sizeof(netif_t));
     572                        if (!netif)
     573                                continue;
     574                       
     575                        netif->handle = -1;
     576                        netif->sess = NULL;
     577                       
     578                        netif->id = generate_new_device_id();
     579                        if (!netif->id) {
     580                                free(netif);
     581                                continue;
     582                        }
     583                       
     584                        rc = measured_strings_initialize(&netif->configuration);
     585                        if (rc != EOK) {
     586                                free(netif);
     587                                continue;
     588                        }
     589                       
     590                        rc = read_netif_configuration(dir_entry->d_name, netif);
     591                        if (rc != EOK) {
     592                                printf("%s: Error reading configuration %s\n", NAME,
     593                                    dir_entry->d_name);
     594                                free(netif);
     595                                continue;
     596                        }
     597                       
     598                        measured_string_t *name = measured_strings_find(&netif->configuration,
     599                            (uint8_t *) CONF_NAME, 0);
     600                        if (!name) {
     601                                printf("%s: Network interface name is missing in %s\n",
     602                                    NAME, dir_entry->d_name);
     603                                measured_strings_destroy(&netif->configuration, free);
     604                                free(netif);
     605                                continue;
     606                        }
     607                       
     608                        netif->name = name->value;
     609                       
     610                        /* Mandatory hardware path */
     611                        measured_string_t *hwpath = measured_strings_find(
     612                            &netif->configuration, (const uint8_t *) CONF_HWPATH, 0);
     613                        if (!hwpath) {
     614                                printf("%s: Hardware path is missing in %s\n",
     615                                    NAME, dir_entry->d_name);
     616                                measured_strings_destroy(&netif->configuration, free);
     617                                free(netif);
     618                                continue;
     619                        }
     620                       
     621                        int index = netifs_add(&net_globals.netifs, netif->id, netif);
     622                        if (index < 0) {
     623                                measured_strings_destroy(&netif->configuration, free);
     624                                free(netif);
     625                                continue;
     626                        }
     627                       
     628                        /*
     629                         * Add to the hardware paths map and init network interfaces
     630                         * and needed modules.
     631                         */
     632                        rc = char_map_add(&net_globals.netif_hwpaths, hwpath->value, 0, index);
     633                        if (rc != EOK) {
     634                                measured_strings_destroy(&netif->configuration, free);
     635                                netifs_exclude_index(&net_globals.netifs, index, free);
     636                                continue;
     637                        }
     638                }
     639               
     640                closedir(config_dir);
     641        }
     642       
     643        rc = add_module(NULL, &net_globals.modules, (uint8_t *) ETHERNET_NAME,
     644            (uint8_t *) ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service);
     645        if (rc != EOK) {
     646                printf("%s: Error adding module '%s'\n", NAME, ETHERNET_NAME);
     647                pm_destroy();
     648                return rc;
     649        }
     650       
     651        rc = add_module(NULL, &net_globals.modules, (uint8_t *) NILDUMMY_NAME,
     652            (uint8_t *) NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service);
     653        if (rc != EOK) {
     654                printf("%s: Error adding module '%s'\n", NAME, NILDUMMY_NAME);
     655                pm_destroy();
     656                return rc;
     657        }
     658       
     659        task_id_t task_id = net_spawn((uint8_t *) IP_FILENAME);
     660        if (!task_id) {
     661                printf("%s: Error spawning IP module\n", NAME);
     662                pm_destroy();
     663                return EINVAL;
     664        }
     665       
     666        rc = add_module(NULL, &net_globals.modules, (uint8_t *) IP_NAME,
     667            (uint8_t *) IP_FILENAME, SERVICE_IP, task_id, ip_connect_module);
     668        if (rc != EOK) {
     669                printf("%s: Error adding module '%s'\n", NAME, IP_NAME);
     670                pm_destroy();
     671                return rc;
     672        }
     673       
     674        if (!net_spawn((uint8_t *) "/srv/icmp")) {
     675                printf("%s: Error spawning ICMP module\n", NAME);
     676                pm_destroy();
     677                return EINVAL;
     678        }
     679       
     680        if (!net_spawn((uint8_t *) "/srv/udp")) {
     681                printf("%s: Error spawning UDP module\n", NAME);
     682                pm_destroy();
     683                return EINVAL;
     684        }
     685       
     686        if (!net_spawn((uint8_t *) "/srv/tcp")) {
     687                printf("%s: Error spawning TCP module\n", NAME);
     688                pm_destroy();
     689                return EINVAL;
     690        }
     691       
     692        rc = service_register(SERVICE_NETWORKING);
     693        if (rc != EOK) {
     694                printf("%s: Error registering service\n", NAME);
     695                pm_destroy();
     696                return rc;
     697        }
     698       
     699        task_retval(0);
     700        async_manager();
     701        return 0;
    708702}
    709703
Note: See TracChangeset for help on using the changeset viewer.