Ignore:
File:
1 edited

Legend:

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

    r5fe7692 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 
    38 #include "net.h"
    39 
     34#include <assert.h>
    4035#include <async.h>
    4136#include <ctype.h>
    4237#include <ddi.h>
    4338#include <errno.h>
     39#include <str_error.h>
    4440#include <malloc.h>
    4541#include <stdio.h>
    4642#include <str.h>
     43#include <devman.h>
    4744#include <str_error.h>
    48 
     45#include <ns.h>
    4946#include <ipc/services.h>
    5047#include <ipc/net.h>
    5148#include <ipc/net_net.h>
    5249#include <ipc/il.h>
     50#include <ipc/ip.h>
    5351#include <ipc/nil.h>
    54 
    55 #include <net/modules.h>
    5652#include <net/packet.h>
    5753#include <net/device.h>
    58 
    5954#include <adt/char_map.h>
    6055#include <adt/generic_char_map.h>
    6156#include <adt/measured_strings.h>
    6257#include <adt/module_map.h>
    63 
    64 #include <netif_remote.h>
    6558#include <nil_remote.h>
    6659#include <net_interface.h>
    6760#include <ip_interface.h>
    68 
    69 /** Networking module name. */
    70 #define NAME  "net"
    71 
    72 /** File read buffer size. */
    73 #define BUFFER_SIZE  256
     61#include <device/nic.h>
     62#include <dirent.h>
     63#include <fcntl.h>
     64#include <cfg.h>
     65#include "net.h"
     66#include "packet_server.h"
     67
     68#define MAX_PATH_LENGTH  1024
    7469
    7570/** Networking module global data. */
     
    7873GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t);
    7974DEVICE_MAP_IMPLEMENT(netifs, netif_t);
    80 
    81 static int startup(void);
    8275
    8376/** Add the configured setting to the configuration map.
     
    9184 *
    9285 */
    93 int add_configuration(measured_strings_t *configuration, const uint8_t *name,
    94     const uint8_t *value)
     86static int add_configuration(measured_strings_t *configuration,
     87    const uint8_t *name, const uint8_t *value)
    9588{
    9689        int rc;
     
    113106/** Generate new system-unique device identifier.
    114107 *
    115  * @return              The system-unique devic identifier.
    116  */
    117 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)
    118112{
    119113        return device_assign_devno();
    120 }
    121 
    122 static int parse_line(measured_strings_t *configuration, uint8_t *line)
    123 {
    124         int rc;
    125        
    126         /* From the beginning */
    127         uint8_t *name = line;
    128        
    129         /* Skip comments and blank lines */
    130         if ((*name == '#') || (*name == '\0'))
    131                 return EOK;
    132        
    133         /* Skip spaces */
    134         while (isspace(*name))
    135                 name++;
    136        
    137         /* Remember the name start */
    138         uint8_t *value = name;
    139        
    140         /* Skip the name */
    141         while (isalnum(*value) || (*value == '_'))
    142                 value++;
    143        
    144         if (*value == '=') {
    145                 /* Terminate the name */
    146                 *value = '\0';
    147         } else {
    148                 /* Terminate the name */
    149                 *value = '\0';
    150                
    151                 /* Skip until '=' */
    152                 value++;
    153                 while ((*value) && (*value != '='))
    154                         value++;
    155                
    156                 /* Not found? */
    157                 if (*value != '=')
    158                         return EINVAL;
    159         }
    160        
    161         value++;
    162        
    163         /* Skip spaces */
    164         while (isspace(*value))
    165                 value++;
    166        
    167         /* Create a bulk measured string till the end */
    168         measured_string_t *setting =
    169             measured_string_create_bulk(value, 0);
    170         if (!setting)
    171                 return ENOMEM;
    172        
    173         /* Add the configuration setting */
    174         rc = measured_strings_add(configuration, name, 0, setting);
    175         if (rc != EOK) {
    176                 free(setting);
    177                 return rc;
    178         }
    179        
    180         return EOK;
    181114}
    182115
     
    186119        printf("%s: Reading configuration file %s/%s\n", NAME, directory, filename);
    187120       
    188         /* Construct the full filename */
    189         char fname[BUFFER_SIZE];
    190         if (snprintf(fname, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE)
    191                 return EOVERFLOW;
    192        
    193         /* Open the file */
    194         FILE *cfg = fopen(fname, "r");
    195         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);
    196128                return ENOENT;
    197        
    198         /*
    199          * Read the configuration line by line
    200          * until an error or the end of file
    201          */
    202         unsigned int line_number = 0;
    203         size_t index = 0;
    204         uint8_t line[BUFFER_SIZE];
    205        
    206         while (!ferror(cfg) && !feof(cfg)) {
    207                 int read = fgetc(cfg);
    208                 if ((read > 0) && (read != '\n') && (read != '\r')) {
    209                         if (index >= BUFFER_SIZE) {
    210                                 line[BUFFER_SIZE - 1] = '\0';
    211                                 fprintf(stderr, "%s: Configuration line %u too "
    212                                     "long: %s\n", NAME, line_number, (char *) line);
    213                                
    214                                 /* No space left in the line buffer */
    215                                 return EOVERFLOW;
    216                         }
    217                         /* Append the character */
    218                         line[index] = (uint8_t) read;
    219                         index++;
    220                 } else {
    221                         /* On error or new line */
    222                         line[index] = '\0';
    223                         line_number++;
    224                         if (parse_line(configuration, line) != EOK) {
    225                                 fprintf(stderr, "%s: Configuration error on "
    226                                     "line %u: %s\n", NAME, line_number, (char *) line);
    227                         }
    228                        
    229                         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;
    230139                }
    231140        }
    232141       
    233         fclose(cfg);
     142        cfg_unload(&cfg);
    234143        return EOK;
    235144}
     
    259168        return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE,
    260169            &net_globals.configuration);
    261 }
    262 
    263 /** Initialize the networking module.
    264  *
    265  * @param[in] client_connection The client connection processing
    266  *                              function. The module skeleton propagates
    267  *                              its own one.
    268  *
    269  * @return EOK on success.
    270  * @return ENOMEM if there is not enough memory left.
    271  *
    272  */
    273 static int net_initialize(async_client_conn_t client_connection)
    274 {
    275         int rc;
    276        
    277         netifs_initialize(&net_globals.netifs);
    278         char_map_initialize(&net_globals.netif_names);
    279         modules_initialize(&net_globals.modules);
    280         measured_strings_initialize(&net_globals.configuration);
    281        
    282         /* TODO: dynamic configuration */
    283         rc = read_configuration();
    284         if (rc != EOK)
    285                 return rc;
    286        
    287         rc = add_module(NULL, &net_globals.modules, (uint8_t *) LO_NAME,
    288             (uint8_t *) LO_FILENAME, SERVICE_LO, 0, connect_to_service);
    289         if (rc != EOK)
    290                 return rc;
    291        
    292         rc = add_module(NULL, &net_globals.modules, (uint8_t *) NE2000_NAME,
    293             (uint8_t *) NE2000_FILENAME, SERVICE_NE2000, 0, connect_to_service);
    294         if (rc != EOK)
    295                 return rc;
    296        
    297         rc = add_module(NULL, &net_globals.modules, (uint8_t *) ETHERNET_NAME,
    298             (uint8_t *) ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service);
    299         if (rc != EOK)
    300                 return rc;
    301        
    302         rc = add_module(NULL, &net_globals.modules, (uint8_t *) NILDUMMY_NAME,
    303             (uint8_t *) NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service);
    304         if (rc != EOK)
    305                 return rc;
    306        
    307         /* Build specific initialization */
    308         return net_initialize_build(client_connection);
    309 }
    310 
    311 /** Start the networking module.
    312  *
    313  * Initializes the client connection serving function,
    314  * initializes the module, registers the module service
    315  * and starts the async manager, processing IPC messages
    316  * in an infinite loop.
    317  *
    318  * @param[in] client_connection The client connection
    319  *                              processing function. The
    320  *                              module skeleton propagates
    321  *                              its own one.
    322  *
    323  * @return EOK on successful module termination.
    324  * @return Other error codes as defined for the net_initialize() function.
    325  * @return Other error codes as defined for the REGISTER_ME() macro function.
    326  *
    327  */
    328 static int net_module_start(async_client_conn_t client_connection)
    329 {
    330         int rc;
    331        
    332         async_set_client_connection(client_connection);
    333         rc = pm_init();
    334         if (rc != EOK)
    335                 return rc;
    336        
    337         rc = net_initialize(client_connection);
    338         if (rc != EOK)
    339                 goto out;
    340        
    341         rc = async_connect_to_me(PHONE_NS, SERVICE_NETWORKING, 0, 0, NULL);
    342         if (rc != EOK)
    343                 goto out;
    344        
    345         rc = startup();
    346         if (rc != EOK)
    347                 goto out;
    348        
    349         task_retval(0);
    350         async_manager();
    351 
    352 out:
    353         pm_destroy();
    354         return rc;
    355170}
    356171
     
    368183 */
    369184static int net_get_conf(measured_strings_t *netif_conf,
    370     measured_string_t *configuration, size_t count, uint8_t **data)
    371 {
    372         if (data)
    373                 *data = NULL;
     185    measured_string_t *configuration, size_t count)
     186{
     187        if ((!configuration) || (count <= 0))
     188                        return EINVAL;
    374189       
    375190        size_t index;
     
    393208}
    394209
    395 int net_get_conf_req(int net_phone, measured_string_t **configuration,
    396     size_t count, uint8_t **data)
    397 {
    398         if (!configuration || (count <= 0))
    399                 return EINVAL;
    400        
    401         return net_get_conf(NULL, *configuration, count, data);
    402 }
    403 
    404 int net_get_device_conf_req(int net_phone, device_id_t device_id,
    405     measured_string_t **configuration, size_t count, uint8_t **data)
    406 {
    407         if ((!configuration) || (count == 0))
    408                 return EINVAL;
    409 
     210static int net_get_device_conf(nic_device_id_t device_id,
     211    measured_string_t *configuration, size_t count)
     212{
    410213        netif_t *netif = netifs_find(&net_globals.netifs, device_id);
    411214        if (netif)
    412                 return net_get_conf(&netif->configuration, *configuration, count, data);
     215                return net_get_conf(&netif->configuration, configuration, count);
    413216        else
    414                 return net_get_conf(NULL, *configuration, count, data);
    415 }
    416 
    417 void net_free_settings(measured_string_t *settings, uint8_t *data)
    418 {
     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);
    419271}
    420272
     
    435287 *
    436288 */
    437 static int start_device(netif_t *netif)
    438 {
    439         int rc;
    440        
    441         /* Mandatory netif */
    442         measured_string_t *setting =
    443             measured_strings_find(&netif->configuration, (uint8_t *) CONF_NETIF, 0);
    444        
    445         netif->driver = get_running_module(&net_globals.modules, setting->value);
    446         if (!netif->driver) {
    447                 fprintf(stderr, "%s: Failed to start network interface driver '%s'\n",
    448                     NAME, setting->value);
    449                 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;
    450299        }
    451300       
    452301        /* Optional network interface layer */
    453         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);
    454304        if (setting) {
    455                 netif->nil = get_running_module(&net_globals.modules, setting->value);
     305                netif->nil = get_running_module(&net_globals.modules,
     306                    setting->value);
    456307                if (!netif->nil) {
    457                         fprintf(stderr, "%s: Failed to start network interface layer '%s'\n",
     308                        printf("%s: Unable to connect to network interface layer '%s'\n",
    458309                            NAME, setting->value);
    459310                        return EINVAL;
     
    463314       
    464315        /* Mandatory internet layer */
    465         setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IL, 0);
    466         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);
    467320        if (!netif->il) {
    468                 fprintf(stderr, "%s: Failed to start internet layer '%s'\n",
     321                printf("%s: Unable to connect to internet layer '%s'\n",
    469322                    NAME, setting->value);
    470323                return EINVAL;
    471324        }
    472325       
    473         /* Hardware configuration */
    474         setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IRQ, 0);
    475         int irq = setting ? strtol((char *) setting->value, NULL, 10) : 0;
    476        
    477         setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_IO, 0);
    478         uintptr_t io = setting ? strtol((char *) setting->value, NULL, 16) : 0;
    479        
    480         rc = netif_probe_req(netif->driver->phone, netif->id, irq, (void *) io);
    481         if (rc != EOK)
    482                 return rc;
    483        
    484326        /* Network interface layer startup */
    485         services_t internet_service;
     327        int rc;
     328        services_t nil_service;
    486329        if (netif->nil) {
    487                 setting = measured_strings_find(&netif->configuration, (uint8_t *) CONF_MTU, 0);
     330                setting = measured_strings_find(&netif->configuration,
     331                    (uint8_t *) CONF_MTU, 0);
    488332                if (!setting)
    489333                        setting = measured_strings_find(&net_globals.configuration,
    490334                            (uint8_t *) CONF_MTU, 0);
    491335               
    492                 int mtu = setting ? strtol((char *) setting->value, NULL, 10) : 0;
    493                
    494                 rc = nil_device_req(netif->nil->phone, netif->id, mtu,
    495                     netif->driver->service);
    496                 if (rc != EOK)
     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);
    497343                        return rc;
    498                
    499                 internet_service = netif->nil->service;
     344                }
     345               
     346                nil_service = netif->nil->service;
    500347        } else
    501                 internet_service = netif->driver->service;
     348                nil_service = -1;
    502349       
    503350        /* Inter-network layer startup */
    504351        switch (netif->il->service) {
    505352        case SERVICE_IP:
    506                 rc = ip_device_req(netif->il->phone, netif->id,
    507                     internet_service);
    508                 if (rc != EOK)
     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);
    509356                        return rc;
     357                }
     358               
    510359                break;
    511360        default:
     
    513362        }
    514363       
    515         return netif_start_req(netif->driver->phone, netif->id);
    516 }
    517 
    518 /** Read the configuration and start all network interfaces.
    519  *
    520  * @return EOK on success.
    521  * @return EXDEV if there is no available system-unique device identifier.
    522  * @return EINVAL if any of the network interface names are not configured.
    523  * @return ENOMEM if there is not enough memory left.
    524  * @return Other error codes as defined for the read_configuration()
    525  *         function.
    526  * @return Other error codes as defined for the read_netif_configuration()
    527  *         function.
    528  * @return Other error codes as defined for the start_device() function.
    529  *
    530  */
    531 static int startup(void)
    532 {
    533         const char *conf_files[] = {
    534                 "lo",
    535                 "ne2k"
    536         };
    537         size_t count = sizeof(conf_files) / sizeof(char *);
    538         int rc;
    539        
    540         size_t i;
    541         for (i = 0; i < count; i++) {
    542                 netif_t *netif = (netif_t *) malloc(sizeof(netif_t));
    543                 if (!netif)
    544                         return ENOMEM;
    545                
    546                 netif->id = generate_new_device_id();
    547                 if (!netif->id)
    548                         return EXDEV;
    549                
    550                 rc = measured_strings_initialize(&netif->configuration);
     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]);
    551407                if (rc != EOK)
    552408                        return rc;
    553                
    554                 /* Read configuration files */
    555                 rc = read_netif_configuration(conf_files[i], netif);
    556                 if (rc != EOK) {
    557                         measured_strings_destroy(&netif->configuration, free);
    558                         free(netif);
    559                         return rc;
    560                 }
    561                
    562                 /* Mandatory name */
    563                 measured_string_t *setting =
    564                     measured_strings_find(&netif->configuration, (uint8_t *) CONF_NAME, 0);
    565                 if (!setting) {
    566                         fprintf(stderr, "%s: Network interface name is missing\n", NAME);
    567                         measured_strings_destroy(&netif->configuration, free);
    568                         free(netif);
    569                         return EINVAL;
    570                 }
    571                 netif->name = setting->value;
    572                
    573                 /* Add to the netifs map */
    574                 int index = netifs_add(&net_globals.netifs, netif->id, netif);
    575                 if (index < 0) {
    576                         measured_strings_destroy(&netif->configuration, free);
    577                         free(netif);
    578                         return index;
    579                 }
    580                
    581                 /*
    582                  * Add to the netif names map and start network interfaces
    583                  * and needed modules.
    584                  */
    585                 rc = char_map_add(&net_globals.netif_names, netif->name, 0,
    586                     index);
    587                 if (rc != EOK) {
    588                         measured_strings_destroy(&netif->configuration, free);
    589                         netifs_exclude_index(&net_globals.netifs, index, free);
    590                         return rc;
    591                 }
    592                
    593                 rc = start_device(netif);
    594                 if (rc != EOK) {
    595                         printf("%s: Ignoring failed interface %s (%s)\n", NAME,
    596                             netif->name, str_error(rc));
    597                         measured_strings_destroy(&netif->configuration, free);
    598                         netifs_exclude_index(&net_globals.netifs, index, free);
    599                         continue;
    600                 }
    601                
    602                 /* Increment modules' usage */
    603                 netif->driver->usage++;
    604                 if (netif->nil)
    605                         netif->nil->usage++;
    606                 netif->il->usage++;
    607                
    608                 printf("%s: Network interface started (name: %s, id: %d, driver: %s, "
    609                     "nil: %s, il: %s)\n", NAME, netif->name, netif->id,
    610                     netif->driver->name, netif->nil ? (char *) netif->nil->name : "[none]",
    611                     netif->il->name);
    612409        }
    613410       
     
    630427 *
    631428 */
    632 int net_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
    633     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)
    634431{
    635432        measured_string_t *strings;
    636433        uint8_t *data;
    637434        int rc;
     435        size_t count;
    638436       
    639437        *answer_count = 0;
     438       
     439        if (!IPC_GET_IMETHOD(*call))
     440                return EOK;
     441       
    640442        switch (IPC_GET_IMETHOD(*call)) {
    641         case IPC_M_PHONE_HUNGUP:
    642                 return EOK;
    643443        case NET_NET_GET_DEVICE_CONF:
    644444                rc = measured_strings_receive(&strings, &data,
     
    646446                if (rc != EOK)
    647447                        return rc;
    648                 net_get_device_conf_req(0, IPC_GET_DEVICE(*call), &strings,
    649                     IPC_GET_COUNT(*call), NULL);
    650                
    651                 /* Strings should not contain received data anymore */
    652                 free(data);
     448               
     449                net_get_device_conf(IPC_GET_DEVICE(*call), strings,
     450                    IPC_GET_COUNT(*call));
    653451               
    654452                rc = measured_strings_reply(strings, IPC_GET_COUNT(*call));
    655453                free(strings);
     454                free(data);
    656455                return rc;
    657456        case NET_NET_GET_CONF:
     
    660459                if (rc != EOK)
    661460                        return rc;
    662                 net_get_conf_req(0, &strings, IPC_GET_COUNT(*call), NULL);
    663                
    664                 /* Strings should not contain received data anymore */
    665                 free(data);
     461               
     462                net_get_conf(NULL, strings, IPC_GET_COUNT(*call));
    666463               
    667464                rc = measured_strings_reply(strings, IPC_GET_COUNT(*call));
    668465                free(strings);
    669                 return rc;
    670         case NET_NET_STARTUP:
    671                 return startup();
    672         }
    673        
    674         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        }
    675488}
    676489
    677490/** Default thread for new connections.
    678491 *
    679  * @param[in] iid The initial message identifier.
     492 * @param[in] iid   The initial message identifier.
    680493 * @param[in] icall The initial message call structure.
    681  *
    682  */
    683 static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     494 * @param[in] arg   Local argument.
     495 *
     496 */
     497static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall,
     498    void *arg)
    684499{
    685500        /*
     
    692507                /* Clear the answer structure */
    693508                ipc_call_t answer;
    694                 size_t answer_count;
    695                 refresh_answer(&answer, &answer_count);
     509                size_t count;
     510                refresh_answer(&answer, &count);
    696511               
    697512                /* Fetch the next message */
     
    700515               
    701516                /* Process the message */
    702                 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);
    703522               
    704523                /* End if told to either by the message or the processing result */
    705                 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
     524                if ((!IPC_GET_IMETHOD(call)) || (res == EHANGUP))
    706525                        return;
    707526               
    708527                /* Answer the message */
    709                 answer_call(callid, res, &answer, answer_count);
     528                answer_call(callid, res, &answer, count);
    710529        }
    711530}
     
    713532int main(int argc, char *argv[])
    714533{
    715         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;
    716702}
    717703
Note: See TracChangeset for help on using the changeset viewer.