Changeset 24ab58b3 in mainline for uspace/srv/net/net/net.c
- Timestamp:
- 2010-04-06T11:41:48Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 14f1db0
- Parents:
- 4dd8529
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/net/net.c
r4dd8529 r24ab58b3 28 28 29 29 /** @addtogroup net 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * Networking subsystem central module implementation. 34 * Networking subsystem central module implementation. 35 * 35 36 */ 36 37 … … 64 65 #include "net.h" 65 66 67 /** Networking module name. 68 * 69 */ 70 #define NAME "net" 71 66 72 /** File read buffer size. 67 */ 68 #define BUFFER_SIZE 256 69 70 /** Networking module name. 71 */ 72 #define NAME "Networking" 73 * 74 */ 75 #define BUFFER_SIZE 256 73 76 74 77 /** Networking module global data. 75 */ 76 net_globals_t net_globals; 77 78 /** Generates new system-unique device identifier. 79 * @returns The system-unique devic identifier. 80 */ 81 device_id_t generate_new_device_id(void); 82 83 /** Returns the configured values. 84 * The network interface configuration is searched first. 85 * @param[in] netif_conf The network interface configuration setting. 86 * @param[out] configuration The found configured values. 87 * @param[in] count The desired settings count. 88 * @param[out] data The found configuration settings data. 89 * @returns EOK. 90 */ 91 int net_get_conf(measured_strings_ref netif_conf, measured_string_ref configuration, size_t count, char ** data); 92 93 /** Initializes the networking module. 94 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 95 * @returns EOK on success. 96 * @returns ENOMEM if there is not enough memory left. 97 */ 98 int net_initialize(async_client_conn_t client_connection); 99 100 /** \todo 101 */ 102 int parse_line(measured_strings_ref configuration, char * line); 103 104 /** Reads the networking subsystem global configuration. 105 * @returns EOK on success. 106 * @returns Other error codes as defined for the add_configuration() function. 107 */ 108 int read_configuration(void); 109 110 /** \todo 111 */ 112 int read_configuration_file(const char * directory, const char * filename, measured_strings_ref configuration); 113 114 /** Reads the network interface specific configuration. 115 * @param[in] name The network interface name. 116 * @param[in,out] netif The network interface structure. 117 * @returns EOK on success. 118 * @returns Other error codes as defined for the add_configuration() function. 119 */ 120 int read_netif_configuration(const char * name, netif_ref netif); 121 122 /** Starts the network interface according to its configuration. 123 * Registers the network interface with the subsystem modules. 124 * Starts the needed subsystem modules. 125 * @param[in] netif The network interface specific data. 126 * @returns EOK on success. 127 * @returns EINVAL if there are some settings missing. 128 * @returns ENOENT if the internet protocol module is not known. 129 * @returns Other error codes as defined for the netif_probe_req() function. 130 * @returns Other error codes as defined for the nil_device_req() function. 131 * @returns Other error codes as defined for the needed internet layer registering function. 132 */ 133 int start_device(netif_ref netif); 134 135 /** Reads the configuration and starts all network interfaces. 136 * @returns EOK on success. 137 * @returns EXDEV if there is no available system-unique device identifier. 138 * @returns EINVAL if any of the network interface names are not configured. 139 * @returns ENOMEM if there is not enough memory left. 140 * @returns Other error codes as defined for the read_configuration() function. 141 * @returns Other error codes as defined for the read_netif_configuration() function. 142 * @returns Other error codes as defined for the start_device() function. 143 */ 144 int startup(void); 145 146 GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t) 147 148 DEVICE_MAP_IMPLEMENT(netifs, netif_t) 149 150 int add_configuration(measured_strings_ref configuration, const char * name, const char * value){ 151 ERROR_DECLARE; 152 153 measured_string_ref setting; 154 155 setting = measured_string_create_bulk(value, 0); 156 if(! setting){ 78 * 79 */ 80 net_globals_t net_globals; 81 82 GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t); 83 DEVICE_MAP_IMPLEMENT(netifs, netif_t); 84 85 /** Add the configured setting to the configuration map. 86 * 87 * @param[in] configuration The configuration map. 88 * @param[in] name The setting name. 89 * @param[in] value The setting value. 90 * 91 * @returns EOK on success. 92 * @returns ENOMEM if there is not enough memory left. 93 * 94 */ 95 int add_configuration(measured_strings_ref configuration, const char *name, 96 const char *value) 97 { 98 ERROR_DECLARE; 99 100 measured_string_ref setting = 101 measured_string_create_bulk(value, 0); 102 103 if (!setting) 157 104 return ENOMEM; 158 }159 / / add the configuration setting160 if (ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){105 106 /* Add the configuration setting */ 107 if (ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))) { 161 108 free(setting); 162 109 return ERROR_CODE; 163 110 } 164 return EOK; 165 } 166 167 device_id_t generate_new_device_id(void){ 111 112 return EOK; 113 } 114 115 /** Generate new system-unique device identifier. 116 * 117 * @returns The system-unique devic identifier. 118 * 119 */ 120 static device_id_t generate_new_device_id(void) 121 { 168 122 return device_assign_devno(); 169 123 } 170 124 171 /** Starts the networking module. 172 * Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop. 173 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 174 * @returns EOK on successful module termination. 175 * @returns Other error codes as defined for the net_initialize() function. 176 * @returns Other error codes as defined for the REGISTER_ME() macro function. 177 */ 178 static int net_module_start(async_client_conn_t client_connection){ 179 ERROR_DECLARE; 180 181 ipcarg_t phonehash; 182 183 async_set_client_connection(client_connection); 184 ERROR_PROPAGATE(pm_init()); 185 if(ERROR_OCCURRED(net_initialize(client_connection)) 186 || ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))){ 187 pm_destroy(); 125 static int parse_line(measured_strings_ref configuration, char *line) 126 { 127 ERROR_DECLARE; 128 129 /* From the beginning */ 130 char *name = line; 131 132 /* Skip comments and blank lines */ 133 if ((*name == '#') || (*name == '\0')) 134 return EOK; 135 136 /* Skip spaces */ 137 while (isspace(*name)) 138 name++; 139 140 /* Remember the name start */ 141 char *value = name; 142 143 /* Skip the name */ 144 while (isalnum(*value) || (*value == '_')) 145 value++; 146 147 if (*value == '=') { 148 /* Terminate the name */ 149 *value = '\0'; 150 } else { 151 /* Terminate the name */ 152 *value = '\0'; 153 154 /* Skip until '=' */ 155 value++; 156 while ((*value) && (*value != '=')) 157 value++; 158 159 /* Not found? */ 160 if (*value != '=') 161 return EINVAL; 162 } 163 164 value++; 165 166 /* Skip spaces */ 167 while (isspace(*value)) 168 value++; 169 170 /* Create a bulk measured string till the end */ 171 measured_string_ref setting = 172 measured_string_create_bulk(value, 0); 173 if (!setting) 174 return ENOMEM; 175 176 /* Add the configuration setting */ 177 if (ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))) { 178 free(setting); 188 179 return ERROR_CODE; 189 180 } 190 191 async_manager(); 192 193 pm_destroy(); 194 return EOK; 195 } 196 197 int net_connect_module(services_t service){ 198 return EOK; 199 } 200 201 void net_free_settings(measured_string_ref settings, char * data){ 202 } 203 204 int net_get_conf(measured_strings_ref netif_conf, measured_string_ref configuration, size_t count, char ** data){ 205 measured_string_ref setting; 206 size_t index; 207 208 if(data){ 209 *data = NULL; 210 } 211 212 for(index = 0; index < count; ++ index){ 213 setting = measured_strings_find(netif_conf, configuration[index].value, 0); 214 if(! setting){ 215 setting = measured_strings_find(&net_globals.configuration, configuration[index].value, 0); 181 182 return EOK; 183 } 184 185 static int read_configuration_file(const char *directory, const char *filename, 186 measured_strings_ref configuration) 187 { 188 ERROR_DECLARE; 189 190 printf("%s: Reading configuration file %s/%s\n", NAME, directory, filename); 191 192 /* Construct the full filename */ 193 char line[BUFFER_SIZE]; 194 if (snprintf(line, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE) 195 return EOVERFLOW; 196 197 /* Open the file */ 198 FILE *cfg = fopen(line, "r"); 199 if (!cfg) 200 return ENOENT; 201 202 /* 203 * Read the configuration line by line 204 * until an error or the end of file 205 */ 206 unsigned int line_number = 0; 207 size_t index = 0; 208 while ((!ferror(cfg)) && (!feof(cfg))) { 209 int read = fgetc(cfg); 210 if ((read > 0) && (read != '\n') && (read != '\r')) { 211 if (index >= BUFFER_SIZE) { 212 line[BUFFER_SIZE - 1] = '\0'; 213 fprintf(stderr, "%s: Configuration line %u too long: %s\n", 214 NAME, line_number, line); 215 216 /* No space left in the line buffer */ 217 return EOVERFLOW; 218 } else { 219 /* Append the character */ 220 line[index] = (char) read; 221 index++; 222 } 223 } else { 224 /* On error or new line */ 225 line[index] = '\0'; 226 line_number++; 227 if (ERROR_OCCURRED(parse_line(configuration, line))) 228 fprintf(stderr, "%s: Configuration error on line %u: %s\n", 229 NAME, line_number, line); 230 231 index = 0; 216 232 } 217 if(setting){ 218 configuration[index].length = setting->length; 219 configuration[index].value = setting->value; 220 }else{ 221 configuration[index].length = 0; 222 configuration[index].value = NULL; 223 } 224 } 225 return EOK; 226 } 227 228 int net_get_conf_req(int net_phone, measured_string_ref * configuration, size_t count, char ** data){ 229 if(!(configuration && (count > 0))){ 230 return EINVAL; 231 } 232 233 return net_get_conf(NULL, * configuration, count, data); 234 } 235 236 int net_get_device_conf_req(int net_phone, device_id_t device_id, measured_string_ref * configuration, size_t count, char ** data){ 237 netif_ref netif; 238 239 if(!(configuration && (count > 0))){ 240 return EINVAL; 241 } 242 243 netif = netifs_find(&net_globals.netifs, device_id); 244 if(netif){ 245 return net_get_conf(&netif->configuration, * configuration, count, data); 246 }else{ 247 return net_get_conf(NULL, * configuration, count, data); 248 } 249 } 250 251 int net_initialize(async_client_conn_t client_connection){ 252 ERROR_DECLARE; 253 233 } 234 235 fclose(cfg); 236 return EOK; 237 } 238 239 /** Read the network interface specific configuration. 240 * 241 * @param[in] name The network interface name. 242 * @param[in,out] netif The network interface structure. 243 * 244 * @returns EOK on success. 245 * @returns Other error codes as defined for the add_configuration() function. 246 * 247 */ 248 static int read_netif_configuration(const char *name, netif_t *netif) 249 { 250 return read_configuration_file(CONF_DIR, name, &netif->configuration); 251 } 252 253 /** Read the networking subsystem global configuration. 254 * 255 * @returns EOK on success. 256 * @returns Other error codes as defined for the add_configuration() function. 257 * 258 */ 259 static int read_configuration(void) 260 { 261 return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE, 262 &net_globals.configuration); 263 } 264 265 /** Initialize the networking module. 266 * 267 * @param[in] client_connection The client connection processing 268 * function. The module skeleton propagates 269 * its own one. 270 * 271 * @returns EOK on success. 272 * @returns ENOMEM if there is not enough memory left. 273 * 274 */ 275 static int net_initialize(async_client_conn_t client_connection) 276 { 277 ERROR_DECLARE; 278 254 279 netifs_initialize(&net_globals.netifs); 255 280 char_map_initialize(&net_globals.netif_names); 256 281 modules_initialize(&net_globals.modules); 257 282 measured_strings_initialize(&net_globals.configuration); 258 259 // TODO dynamic configuration283 284 // TODO: dynamic configuration 260 285 ERROR_PROPAGATE(read_configuration()); 261 262 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, LO_NAME, LO_FILENAME, SERVICE_LO, 0, connect_to_service)); 263 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, DP8390_NAME, DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service)); 264 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service)); 265 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, NILDUMMY_NAME, NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service)); 266 267 // build specific initialization 286 287 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, 288 LO_NAME, LO_FILENAME, SERVICE_LO, 0, connect_to_service)); 289 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, 290 DP8390_NAME, DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service)); 291 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, 292 ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0, 293 connect_to_service)); 294 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, 295 NILDUMMY_NAME, NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, 296 connect_to_service)); 297 298 /* Build specific initialization */ 268 299 return net_initialize_build(client_connection); 269 300 } 270 301 271 int net_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 272 ERROR_DECLARE; 273 302 /** Start the networking module. 303 * 304 * Initializes the client connection serving function, 305 * initializes the module, registers the module service 306 * and starts the async manager, processing IPC messages 307 * in an infinite loop. 308 * 309 * @param[in] client_connection The client connection 310 * processing function. The 311 * module skeleton propagates 312 * its own one. 313 * 314 * @returns EOK on successful module termination. 315 * @returns Other error codes as defined for the net_initialize() function. 316 * @returns Other error codes as defined for the REGISTER_ME() macro function. 317 * 318 */ 319 static int net_module_start(async_client_conn_t client_connection) 320 { 321 ERROR_DECLARE; 322 323 async_set_client_connection(client_connection); 324 ERROR_PROPAGATE(pm_init()); 325 326 ipcarg_t phonehash; 327 328 if (ERROR_OCCURRED(net_initialize(client_connection)) 329 || ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))){ 330 pm_destroy(); 331 return ERROR_CODE; 332 } 333 334 async_manager(); 335 336 pm_destroy(); 337 return EOK; 338 } 339 340 /** Return the configured values. 341 * 342 * The network interface configuration is searched first. 343 & 344 * @param[in] netif_conf The network interface configuration setting. 345 * @param[out] configuration The found configured values. 346 * @param[in] count The desired settings count. 347 * @param[out] data The found configuration settings data. 348 * 349 * @returns EOK. 350 * 351 */ 352 static int net_get_conf(measured_strings_ref netif_conf, 353 measured_string_ref configuration, size_t count, char **data) 354 { 355 if (data) 356 *data = NULL; 357 358 size_t index; 359 for (index = 0; index < count; index++) { 360 measured_string_ref setting = 361 measured_strings_find(netif_conf, configuration[index].value, 0); 362 if (!setting) 363 setting = measured_strings_find(&net_globals.configuration, 364 configuration[index].value, 0); 365 366 if (setting) { 367 configuration[index].length = setting->length; 368 configuration[index].value = setting->value; 369 } else { 370 configuration[index].length = 0; 371 configuration[index].value = NULL; 372 } 373 } 374 375 return EOK; 376 } 377 378 int net_get_conf_req(int net_phone, measured_string_ref *configuration, 379 size_t count, char **data) 380 { 381 if (!(configuration && (count > 0))) 382 return EINVAL; 383 384 return net_get_conf(NULL, *configuration, count, data); 385 } 386 387 int net_get_device_conf_req(int net_phone, device_id_t device_id, 388 measured_string_ref *configuration, size_t count, char **data) 389 { 390 if ((!configuration) || (count == 0)) 391 return EINVAL; 392 393 netif_t *netif = netifs_find(&net_globals.netifs, device_id); 394 if (netif) 395 return net_get_conf(&netif->configuration, *configuration, count, data); 396 else 397 return net_get_conf(NULL, *configuration, count, data); 398 } 399 400 void net_free_settings(measured_string_ref settings, char *data) 401 { 402 } 403 404 /** Start the network interface according to its configuration. 405 * 406 * Register the network interface with the subsystem modules. 407 * Start the needed subsystem modules. 408 * 409 * @param[in] netif The network interface specific data. 410 * 411 * @returns EOK on success. 412 * @returns EINVAL if there are some settings missing. 413 * @returns ENOENT if the internet protocol module is not known. 414 * @returns Other error codes as defined for the netif_probe_req() function. 415 * @returns Other error codes as defined for the nil_device_req() function. 416 * @returns Other error codes as defined for the needed internet layer 417 * registering function. 418 * 419 */ 420 static int start_device(netif_t *netif) 421 { 422 ERROR_DECLARE; 423 424 /* Mandatory netif */ 425 measured_string_ref setting = 426 measured_strings_find(&netif->configuration, CONF_NETIF, 0); 427 428 netif->driver = get_running_module(&net_globals.modules, setting->value); 429 if (!netif->driver) { 430 fprintf(stderr, "%s: Failed to start network interface driver '%s'\n", 431 NAME, setting->value); 432 return EINVAL; 433 } 434 435 /* Optional network interface layer */ 436 setting = measured_strings_find(&netif->configuration, CONF_NIL, 0); 437 if (setting) { 438 netif->nil = get_running_module(&net_globals.modules, setting->value); 439 if (!netif->nil) { 440 fprintf(stderr, "%s: Failed to start network interface layer '%s'\n", 441 NAME, setting->value); 442 return EINVAL; 443 } 444 } else 445 netif->nil = NULL; 446 447 /* Mandatory internet layer */ 448 setting = measured_strings_find(&netif->configuration, CONF_IL, 0); 449 netif->il = get_running_module(&net_globals.modules, setting->value); 450 if (!netif->il) { 451 fprintf(stderr, "%s: Failed to start internet layer '%s'\n", 452 NAME, setting->value); 453 return EINVAL; 454 } 455 456 /* Hardware configuration */ 457 setting = measured_strings_find(&netif->configuration, CONF_IRQ, 0); 458 int irq = setting ? strtol(setting->value, NULL, 10) : 0; 459 460 setting = measured_strings_find(&netif->configuration, CONF_IO, 0); 461 int io = setting ? strtol(setting->value, NULL, 16) : 0; 462 463 ERROR_PROPAGATE(netif_probe_req(netif->driver->phone, netif->id, irq, io)); 464 465 /* Network interface layer startup */ 466 services_t internet_service; 467 if (netif->nil) { 468 setting = measured_strings_find(&netif->configuration, CONF_MTU, 0); 469 if (!setting) 470 setting = measured_strings_find(&net_globals.configuration, 471 CONF_MTU, 0); 472 473 int mtu = setting ? strtol(setting->value, NULL, 10) : 0; 474 475 ERROR_PROPAGATE(nil_device_req(netif->nil->phone, netif->id, mtu, 476 netif->driver->service)); 477 478 internet_service = netif->nil->service; 479 } else 480 internet_service = netif->driver->service; 481 482 /* Inter-network layer startup */ 483 switch (netif->il->service) { 484 case SERVICE_IP: 485 ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id, 486 internet_service)); 487 break; 488 default: 489 return ENOENT; 490 } 491 492 ERROR_PROPAGATE(netif_start_req(netif->driver->phone, netif->id)); 493 return EOK; 494 } 495 496 /** Read the configuration and start all network interfaces. 497 * 498 * @returns EOK on success. 499 * @returns EXDEV if there is no available system-unique device identifier. 500 * @returns EINVAL if any of the network interface names are not configured. 501 * @returns ENOMEM if there is not enough memory left. 502 * @returns Other error codes as defined for the read_configuration() 503 * function. 504 * @returns Other error codes as defined for the read_netif_configuration() 505 * function. 506 * @returns Other error codes as defined for the start_device() function. 507 * 508 */ 509 static int startup(void) 510 { 511 ERROR_DECLARE; 512 513 const char *conf_files[] = {"lo", "ne2k"}; 514 size_t count = sizeof(conf_files) / sizeof(char *); 515 516 size_t i; 517 for (i = 0; i < count; i++) { 518 netif_t *netif = (netif_t *) malloc(sizeof(netif_t)); 519 if (!netif) 520 return ENOMEM; 521 522 netif->id = generate_new_device_id(); 523 if (!netif->id) 524 return EXDEV; 525 526 ERROR_PROPAGATE(measured_strings_initialize(&netif->configuration)); 527 528 /* Read configuration files */ 529 if (ERROR_OCCURRED(read_netif_configuration(conf_files[i], netif))) { 530 measured_strings_destroy(&netif->configuration); 531 free(netif); 532 return ERROR_CODE; 533 } 534 535 /* Mandatory name */ 536 measured_string_ref setting = 537 measured_strings_find(&netif->configuration, CONF_NAME, 0); 538 if (!setting) { 539 fprintf(stderr, "%s: Network interface name is missing\n", NAME); 540 measured_strings_destroy(&netif->configuration); 541 free(netif); 542 return EINVAL; 543 } 544 netif->name = setting->value; 545 546 /* Add to the netifs map */ 547 int index = netifs_add(&net_globals.netifs, netif->id, netif); 548 if (index < 0) { 549 measured_strings_destroy(&netif->configuration); 550 free(netif); 551 return index; 552 } 553 554 /* 555 * Add to the netif names map and start network interfaces 556 * and needed modules. 557 */ 558 if ((ERROR_OCCURRED(char_map_add(&net_globals.netif_names, 559 netif->name, 0, index))) || (ERROR_OCCURRED(start_device(netif)))) { 560 measured_strings_destroy(&netif->configuration); 561 netifs_exclude_index(&net_globals.netifs, index); 562 return ERROR_CODE; 563 } 564 565 /* Increment modules' usage */ 566 netif->driver->usage++; 567 if (netif->nil) 568 netif->nil->usage++; 569 netif->il->usage++; 570 571 printf("%s: Network interface started (name: %s, id: %d, driver: %s, " 572 "nil: %s, il: %s)\n", NAME, netif->name, netif->id, 573 netif->driver->name, netif->nil ? netif->nil->name : "[none]", 574 netif->il->name); 575 } 576 577 return EOK; 578 } 579 580 /** Process the networking message. 581 * 582 * @param[in] callid The message identifier. 583 * @param[in] call The message parameters. 584 * @param[out] answer The message answer parameters. 585 * @param[out] answer_count The last parameter for the actual answer 586 * in the answer parameter. 587 * 588 * @returns EOK on success. 589 * @returns ENOTSUP if the message is not known. 590 * 591 * @see net_interface.h 592 * @see IS_NET_NET_MESSAGE() 593 * 594 */ 595 int net_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 596 int *answer_count) 597 { 598 ERROR_DECLARE; 599 274 600 measured_string_ref strings; 275 char * 276 601 char *data; 602 277 603 *answer_count = 0; 278 switch (IPC_GET_METHOD(*call)){604 switch (IPC_GET_METHOD(*call)) { 279 605 case IPC_M_PHONE_HUNGUP: 280 606 return EOK; 281 607 case NET_NET_GET_DEVICE_CONF: 282 ERROR_PROPAGATE(measured_strings_receive(&strings, &data, IPC_GET_COUNT(call))); 283 net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings, IPC_GET_COUNT(call), NULL); 284 // strings should not contain received data anymore 608 ERROR_PROPAGATE(measured_strings_receive(&strings, &data, 609 IPC_GET_COUNT(call))); 610 net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings, 611 IPC_GET_COUNT(call), NULL); 612 613 /* Strings should not contain received data anymore */ 285 614 free(data); 615 286 616 ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call)); 287 617 free(strings); 288 618 return ERROR_CODE; 289 619 case NET_NET_GET_CONF: 290 ERROR_PROPAGATE(measured_strings_receive(&strings, &data, IPC_GET_COUNT(call))); 620 ERROR_PROPAGATE(measured_strings_receive(&strings, &data, 621 IPC_GET_COUNT(call))); 291 622 net_get_conf_req(0, &strings, IPC_GET_COUNT(call), NULL); 292 // strings should not contain received data anymore 623 624 /* Strings should not contain received data anymore */ 293 625 free(data); 626 294 627 ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call)); 295 628 free(strings); … … 301 634 } 302 635 303 int parse_line(measured_strings_ref configuration, char * line){304 ERROR_DECLARE;305 306 measured_string_ref setting;307 char * name;308 char * value;309 310 // from the beginning311 name = line;312 313 // skip comments and blank lines314 if((*name == '#') || (*name == '\0')){315 return EOK;316 }317 // skip spaces318 while(isspace(*name)){319 ++ name;320 }321 322 // remember the name start323 value = name;324 // skip the name325 while(isalnum(*value) || (*value == '_')){326 // make uppercase327 // *value = toupper(*value);328 ++ value;329 }330 331 if(*value == '='){332 // terminate the name333 *value = '\0';334 }else{335 // terminate the name336 *value = '\0';337 // skip until '='338 ++ value;339 while((*value) && (*value != '=')){340 ++ value;341 }342 // not found?343 if(*value != '='){344 return EINVAL;345 }346 }347 348 ++ value;349 // skip spaces350 while(isspace(*value)){351 ++ value;352 }353 // create a bulk measured string till the end354 setting = measured_string_create_bulk(value, 0);355 if(! setting){356 return ENOMEM;357 }358 359 // add the configuration setting360 if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){361 free(setting);362 return ERROR_CODE;363 }364 return EOK;365 }366 367 int read_configuration(void){368 // read the general configuration file369 return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE, &net_globals.configuration);370 }371 372 int read_configuration_file(const char * directory, const char * filename, measured_strings_ref configuration){373 ERROR_DECLARE;374 375 size_t index = 0;376 char line[BUFFER_SIZE];377 FILE * cfg;378 int read;379 int line_number = 0;380 381 // construct the full filename382 printf("Reading file %s/%s\n", directory, filename);383 if(snprintf(line, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE){384 return EOVERFLOW;385 }386 // open the file387 cfg = fopen(line, "r");388 if(! cfg){389 return ENOENT;390 }391 392 // read the configuration line by line393 // until an error or the end of file394 while((! ferror(cfg)) && (! feof(cfg))){395 read = fgetc(cfg);396 if((read > 0) && (read != '\n') && (read != '\r')){397 if(index >= BUFFER_SIZE){398 line[BUFFER_SIZE - 1] = '\0';399 printf("line %d too long: %s\n", line_number, line);400 // no space left in the line buffer401 return EOVERFLOW;402 }else{403 // append the character404 line[index] = (char) read;405 ++ index;406 }407 }else{408 // on error or new line409 line[index] = '\0';410 ++ line_number;411 if(ERROR_OCCURRED(parse_line(configuration, line))){412 printf("error on line %d: %s\n", line_number, line);413 //fclose(cfg);414 //return ERROR_CODE;415 }416 index = 0;417 }418 }419 fclose(cfg);420 return EOK;421 }422 423 int read_netif_configuration(const char * name, netif_ref netif){424 // read the netif configuration file425 return read_configuration_file(CONF_DIR, name, &netif->configuration);426 }427 428 int start_device(netif_ref netif){429 ERROR_DECLARE;430 431 measured_string_ref setting;432 services_t internet_service;433 int irq;434 int io;435 int mtu;436 437 // mandatory netif438 setting = measured_strings_find(&netif->configuration, CONF_NETIF, 0);439 netif->driver = get_running_module(&net_globals.modules, setting->value);440 if(! netif->driver){441 printf("Failed to start the network interface driver %s\n", setting->value);442 return EINVAL;443 }444 445 // optional network interface layer446 setting = measured_strings_find(&netif->configuration, CONF_NIL, 0);447 if(setting){448 netif->nil = get_running_module(&net_globals.modules, setting->value);449 if(! netif->nil){450 printf("Failed to start the network interface layer %s\n", setting->value);451 return EINVAL;452 }453 }else{454 netif->nil = NULL;455 }456 457 // mandatory internet layer458 setting = measured_strings_find(&netif->configuration, CONF_IL, 0);459 netif->il = get_running_module(&net_globals.modules, setting->value);460 if(! netif->il){461 printf("Failed to start the internet layer %s\n", setting->value);462 return EINVAL;463 }464 465 // hardware configuration466 setting = measured_strings_find(&netif->configuration, CONF_IRQ, 0);467 irq = setting ? strtol(setting->value, NULL, 10) : 0;468 setting = measured_strings_find(&netif->configuration, CONF_IO, 0);469 io = setting ? strtol(setting->value, NULL, 16) : 0;470 ERROR_PROPAGATE(netif_probe_req(netif->driver->phone, netif->id, irq, io));471 472 // network interface layer startup473 if(netif->nil){474 setting = measured_strings_find(&netif->configuration, CONF_MTU, 0);475 if(! setting){476 setting = measured_strings_find(&net_globals.configuration, CONF_MTU, 0);477 }478 mtu = setting ? strtol(setting->value, NULL, 10) : 0;479 ERROR_PROPAGATE(nil_device_req(netif->nil->phone, netif->id, mtu, netif->driver->service));480 internet_service = netif->nil->service;481 }else{482 internet_service = netif->driver->service;483 }484 485 // inter-network layer startup486 switch(netif->il->service){487 case SERVICE_IP:488 ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id, internet_service));489 break;490 default:491 return ENOENT;492 }493 ERROR_PROPAGATE(netif_start_req(netif->driver->phone, netif->id));494 return EOK;495 }496 497 int startup(void){498 ERROR_DECLARE;499 500 const char * conf_files[] = {"lo", "ne2k"};501 502 int count = sizeof(conf_files) / sizeof(char *);503 int index;504 netif_ref netif;505 int i;506 measured_string_ref setting;507 508 for(i = 0; i < count; ++ i){509 netif = (netif_ref) malloc(sizeof(netif_t));510 if(! netif){511 return ENOMEM;512 }513 514 netif->id = generate_new_device_id();515 if(! netif->id){516 return EXDEV;517 }518 ERROR_PROPAGATE(measured_strings_initialize(&netif->configuration));519 520 // read configuration files521 if(ERROR_OCCURRED(read_netif_configuration(conf_files[i], netif))){522 measured_strings_destroy(&netif->configuration);523 free(netif);524 return ERROR_CODE;525 }526 527 // mandatory name528 setting = measured_strings_find(&netif->configuration, CONF_NAME, 0);529 if(! setting){530 printf("The name is missing\n");531 measured_strings_destroy(&netif->configuration);532 free(netif);533 return EINVAL;534 }535 netif->name = setting->value;536 537 // add to the netifs map538 index = netifs_add(&net_globals.netifs, netif->id, netif);539 if(index < 0){540 measured_strings_destroy(&netif->configuration);541 free(netif);542 return index;543 }544 545 // add to the netif names map546 if(ERROR_OCCURRED(char_map_add(&net_globals.netif_names, netif->name, 0, index))547 // start network interfaces and needed modules548 || ERROR_OCCURRED(start_device(netif))){549 measured_strings_destroy(&netif->configuration);550 netifs_exclude_index(&net_globals.netifs, index);551 return ERROR_CODE;552 }553 554 // increment modules' usage555 ++ netif->driver->usage;556 if(netif->nil){557 ++ netif->nil->usage;558 }559 ++ netif->il->usage;560 printf("New network interface started:\n\tname\t= %s\n\tid\t= %d\n\tdriver\t= %s\n\tnil\t= %s\n\til\t= %s\n", netif->name, netif->id, netif->driver->name, netif->nil ? netif->nil->name : NULL, netif->il->name);561 }562 return EOK;563 }564 565 636 /** Default thread for new connections. 566 637 * 567 * 568 * 569 * 570 */ 571 static void net_client_connection(ipc_callid_t iid, ipc_call_t * 638 * @param[in] iid The initial message identifier. 639 * @param[in] icall The initial message call structure. 640 * 641 */ 642 static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall) 572 643 { 573 644 /* … … 577 648 ipc_answer_0(iid, EOK); 578 649 579 while(true) { 650 while (true) { 651 /* Clear the answer structure */ 580 652 ipc_call_t answer; 581 653 int answer_count; 582 583 /* Clear the answer structure */584 654 refresh_answer(&answer, &answer_count); 585 655 … … 600 670 } 601 671 602 /** Starts the module.603 *604 * @param argc The count of the command line arguments. Ignored parameter.605 * @param argv The command line parameters. Ignored parameter.606 *607 * @returns EOK on success.608 * @returns Other error codes as defined for each specific module start function.609 *610 */611 672 int main(int argc, char *argv[]) 612 673 { 613 674 ERROR_DECLARE; 614 675 615 /* Print the module label */616 printf("Task %d - %s\n", task_get_id(), NAME);617 618 /* Start the module */619 676 if (ERROR_OCCURRED(net_module_start(net_client_connection))) { 620 printf(" - ERROR %i\n", ERROR_CODE);677 fprintf(stderr, "%s: net_module_start error %i\n", NAME, ERROR_CODE); 621 678 return ERROR_CODE; 622 679 }
Note:
See TracChangeset
for help on using the changeset viewer.