Changes in uspace/srv/net/net/net.c [ee2fa30a:00d7e1b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/net/net.c
ree2fa30a r00d7e1b 1 1 /* 2 2 * Copyright (c) 2009 Lukas Mejdrech 3 * Copyright (c) 2011 Radim Vansa 3 4 * All rights reserved. 4 5 * … … 31 32 */ 32 33 33 /** @file 34 * Networking subsystem central module implementation. 35 * 36 */ 37 34 #include <assert.h> 38 35 #include <async.h> 39 36 #include <ctype.h> 40 37 #include <ddi.h> 41 38 #include <errno.h> 39 #include <str_error.h> 42 40 #include <malloc.h> 43 41 #include <stdio.h> 44 42 #include <str.h> 43 #include <devman.h> 45 44 #include <str_error.h> 46 45 #include <ns.h> … … 49 48 #include <ipc/net_net.h> 50 49 #include <ipc/il.h> 50 #include <ipc/ip.h> 51 51 #include <ipc/nil.h> 52 #include <net/modules.h>53 52 #include <net/packet.h> 54 53 #include <net/device.h> … … 57 56 #include <adt/measured_strings.h> 58 57 #include <adt/module_map.h> 59 #include <netif_remote.h>60 58 #include <nil_remote.h> 61 59 #include <net_interface.h> 62 60 #include <ip_interface.h> 61 #include <device/nic.h> 62 #include <dirent.h> 63 #include <fcntl.h> 64 #include <cfg.h> 63 65 #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 70 69 71 70 /** Networking module global data. */ … … 74 73 GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t); 75 74 DEVICE_MAP_IMPLEMENT(netifs, netif_t); 76 77 static int startup(void);78 75 79 76 /** Add the configured setting to the configuration map. … … 87 84 * 88 85 */ 89 int add_configuration(measured_strings_t *configuration, const uint8_t *name,90 const uint8_t * value)86 static int add_configuration(measured_strings_t *configuration, 87 const uint8_t *name, const uint8_t *value) 91 88 { 92 89 int rc; … … 109 106 /** Generate new system-unique device identifier. 110 107 * 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 */ 111 static nic_device_id_t generate_new_device_id(void) 114 112 { 115 113 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;177 114 } 178 115 … … 182 119 printf("%s: Reading configuration file %s/%s\n", NAME, directory, filename); 183 120 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); 192 128 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; 226 139 } 227 140 } 228 141 229 fclose(cfg);142 cfg_unload(&cfg); 230 143 return EOK; 231 144 } … … 255 168 return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE, 256 169 &net_globals.configuration); 257 }258 259 /** Initialize the networking module.260 *261 * @param[in] client_connection The client connection processing262 * function. The module skeleton propagates263 * 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 service311 * and starts the async manager, processing IPC messages312 * in an infinite loop.313 *314 * @param[in] client_connection The client connection315 * processing function. The316 * module skeleton propagates317 * 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;351 170 } 352 171 … … 364 183 */ 365 184 static 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; 370 189 371 190 size_t index; … … 389 208 } 390 209 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 210 static int net_get_device_conf(nic_device_id_t device_id, 211 measured_string_t *configuration, size_t count) 212 { 406 213 netif_t *netif = netifs_find(&net_globals.netifs, device_id); 407 214 if (netif) 408 return net_get_conf(&netif->configuration, *configuration, count, data);215 return net_get_conf(&netif->configuration, configuration, count); 409 216 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 220 static 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 250 static 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 264 static 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); 415 271 } 416 272 … … 431 287 * 432 288 */ 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; 289 static 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; 446 299 } 447 300 448 301 /* 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); 450 304 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); 452 307 if (!netif->nil) { 453 fprintf(stderr, "%s: Failed to startnetwork interface layer '%s'\n",308 printf("%s: Unable to connect to network interface layer '%s'\n", 454 309 NAME, setting->value); 455 310 return EINVAL; … … 459 314 460 315 /* 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); 463 320 if (!netif->il) { 464 fprintf(stderr, "%s: Failed to startinternet layer '%s'\n",321 printf("%s: Unable to connect to internet layer '%s'\n", 465 322 NAME, setting->value); 466 323 return EINVAL; 467 324 } 468 325 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 480 326 /* Network interface layer startup */ 481 services_t internet_service; 327 int rc; 328 services_t nil_service; 482 329 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); 484 332 if (!setting) 485 333 setting = measured_strings_find(&net_globals.configuration, 486 334 (uint8_t *) CONF_MTU, 0); 487 335 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 368 static 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 397 static 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]); 491 407 if (rc != EOK) 492 408 return rc; 493 494 internet_service = netif->nil->service;495 } else496 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 interfaces571 * 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);600 409 } 601 410 … … 618 427 * 619 428 */ 620 int net_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,621 size_t *answer_count)429 static int net_message(ipc_callid_t callid, ipc_call_t *call, 430 ipc_call_t *answer, size_t *answer_count) 622 431 { 623 432 measured_string_t *strings; 624 433 uint8_t *data; 625 434 int rc; 435 size_t count; 626 436 627 437 *answer_count = 0; … … 636 446 if (rc != EOK) 637 447 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)); 643 451 644 452 rc = measured_strings_reply(strings, IPC_GET_COUNT(*call)); 645 453 free(strings); 454 free(data); 646 455 return rc; 647 456 case NET_NET_GET_CONF: … … 650 459 if (rc != EOK) 651 460 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)); 656 463 657 464 rc = measured_strings_reply(strings, IPC_GET_COUNT(*call)); 658 465 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 } 665 488 } 666 489 … … 684 507 /* Clear the answer structure */ 685 508 ipc_call_t answer; 686 size_t answer_count;687 refresh_answer(&answer, & answer_count);509 size_t count; 510 refresh_answer(&answer, &count); 688 511 689 512 /* Fetch the next message */ … … 692 515 693 516 /* 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); 695 522 696 523 /* End if told to either by the message or the processing result */ … … 699 526 700 527 /* Answer the message */ 701 answer_call(callid, res, &answer, answer_count);528 answer_call(callid, res, &answer, count); 702 529 } 703 530 } … … 705 532 int main(int argc, char *argv[]) 706 533 { 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; 708 702 } 709 703
Note:
See TracChangeset
for help on using the changeset viewer.