Changes in uspace/srv/net/il/ip/ip.c [ffa2c8ef:7e752b2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/il/ip/ip.c
rffa2c8ef r7e752b2 36 36 */ 37 37 38 #include "ip.h" 39 #include "ip_module.h" 40 38 41 #include <async.h> 39 42 #include <errno.h> … … 41 44 #include <stdio.h> 42 45 #include <str.h> 46 #include <ipc/ipc.h> 43 47 #include <ipc/services.h> 44 48 #include <ipc/net.h> … … 48 52 #include <sys/types.h> 49 53 #include <byteorder.h> 50 #include "ip.h"51 54 52 55 #include <adt/measured_strings.h> … … 66 69 #include <net_checksum.h> 67 70 #include <icmp_client.h> 68 #include <icmp_remote.h> 71 #include <icmp_interface.h> 72 #include <il_interface.h> 69 73 #include <ip_client.h> 70 74 #include <ip_interface.h> 71 75 #include <ip_header.h> 72 76 #include <net_interface.h> 73 #include <nil_ remote.h>74 #include <tl_ remote.h>77 #include <nil_interface.h> 78 #include <tl_interface.h> 75 79 #include <packet_remote.h> 76 #include <il_remote.h> 77 #include <il_skel.h> 80 #include <il_local.h> 78 81 79 82 /** IP module name. */ … … 119 122 INT_MAP_IMPLEMENT(ip_protos, ip_proto_t); 120 123 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t); 121 122 static void ip_receiver(ipc_callid_t, ipc_call_t *);123 124 124 125 /** Releases the packet and returns the result. … … 243 244 } 244 245 245 int il_initialize(int net_phone) 246 { 246 /** Initializes the IP module. 247 * 248 * @param[in] client_connection The client connection processing function. The 249 * module skeleton propagates its own one. 250 * @return EOK on success. 251 * @return ENOMEM if there is not enough memory left. 252 */ 253 int ip_initialize(async_client_conn_t client_connection) 254 { 255 int rc; 256 247 257 fibril_rwlock_initialize(&ip_globals.lock); 248 258 fibril_rwlock_write_lock(&ip_globals.lock); 249 259 fibril_rwlock_initialize(&ip_globals.protos_lock); 250 260 fibril_rwlock_initialize(&ip_globals.netifs_lock); 251 252 ip_globals.net_phone = net_phone;253 261 ip_globals.packet_counter = 0; 254 262 ip_globals.gateway.address.s_addr = 0; … … 256 264 ip_globals.gateway.gateway.s_addr = 0; 257 265 ip_globals.gateway.netif = NULL; 258 259 int rc = ip_netifs_initialize(&ip_globals.netifs); 266 ip_globals.client_connection = client_connection; 267 268 rc = ip_netifs_initialize(&ip_globals.netifs); 260 269 if (rc != EOK) 261 270 goto out; … … 266 275 if (rc != EOK) 267 276 goto out; 268 rc = add_module(NULL, &ip_globals.modules, (uint8_t *) ARP_NAME,269 (uint8_t *) ARP_FILENAME,SERVICE_ARP, 0, arp_connect_module);277 rc = add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME, 278 SERVICE_ARP, 0, arp_connect_module); 270 279 271 280 out: … … 303 312 measured_string_t names[] = { 304 313 { 305 ( uint8_t*) "IPV",314 (char *) "IPV", 306 315 3 307 316 }, 308 317 { 309 ( uint8_t*) "IP_CONFIG",318 (char *) "IP_CONFIG", 310 319 9 311 320 }, 312 321 { 313 ( uint8_t*) "IP_ADDR",322 (char *) "IP_ADDR", 314 323 7 315 324 }, 316 325 { 317 ( uint8_t*) "IP_NETMASK",326 (char *) "IP_NETMASK", 318 327 10 319 328 }, 320 329 { 321 ( uint8_t*) "IP_GATEWAY",330 (char *) "IP_GATEWAY", 322 331 10 323 332 }, 324 333 { 325 ( uint8_t*) "IP_BROADCAST",334 (char *) "IP_BROADCAST", 326 335 12 327 336 }, 328 337 { 329 ( uint8_t*) "ARP",338 (char *) "ARP", 330 339 3 331 340 }, 332 341 { 333 ( uint8_t*) "IP_ROUTING",342 (char *) "IP_ROUTING", 334 343 10 335 344 } … … 337 346 measured_string_t *configuration; 338 347 size_t count = sizeof(names) / sizeof(measured_string_t); 339 uint8_t*data;348 char *data; 340 349 measured_string_t address; 341 350 ip_route_t *route; … … 359 368 if (configuration) { 360 369 if (configuration[0].value) 361 ip_netif->ipv = strtol( (char *)configuration[0].value, NULL, 0);362 363 ip_netif->dhcp = !str_lcmp( (char *)configuration[1].value, "dhcp",370 ip_netif->ipv = strtol(configuration[0].value, NULL, 0); 371 372 ip_netif->dhcp = !str_lcmp(configuration[1].value, "dhcp", 364 373 configuration[1].length); 365 374 … … 385 394 } 386 395 387 if ((inet_pton(AF_INET, (char *)configuration[2].value,396 if ((inet_pton(AF_INET, configuration[2].value, 388 397 (uint8_t *) &route->address.s_addr) != EOK) || 389 (inet_pton(AF_INET, (char *)configuration[3].value,398 (inet_pton(AF_INET, configuration[3].value, 390 399 (uint8_t *) &route->netmask.s_addr) != EOK) || 391 (inet_pton(AF_INET, (char *)configuration[4].value,400 (inet_pton(AF_INET, configuration[4].value, 392 401 (uint8_t *) &gateway.s_addr) == EINVAL) || 393 (inet_pton(AF_INET, (char *)configuration[5].value,402 (inet_pton(AF_INET, configuration[5].value, 394 403 (uint8_t *) &ip_netif->broadcast.s_addr) == EINVAL)) 395 404 { … … 421 430 // binds the netif service which also initializes the device 422 431 ip_netif->phone = nil_bind_service(ip_netif->service, 423 ( sysarg_t) ip_netif->device_id, SERVICE_IP,424 ip_ receiver);432 (ipcarg_t) ip_netif->device_id, SERVICE_IP, 433 ip_globals.client_connection); 425 434 if (ip_netif->phone < 0) { 426 435 printf("Failed to contact the nil service %d\n", … … 432 441 if (ip_netif->arp) { 433 442 if (route) { 434 address.value = ( uint8_t*) &route->address.s_addr;435 address.length = sizeof(in_addr_t);443 address.value = (char *) &route->address.s_addr; 444 address.length = CONVERT_SIZE(in_addr_t, char, 1); 436 445 437 446 rc = arp_device_req(ip_netif->arp->phone, … … 468 477 ip_globals.gateway.gateway.s_addr = gateway.s_addr; 469 478 ip_globals.gateway.netif = ip_netif; 470 471 char defgateway[INET_ADDRSTRLEN];472 inet_ntop(AF_INET, (uint8_t *) &gateway.s_addr,473 defgateway, INET_ADDRSTRLEN);474 printf("%s: Default gateway (%s)\n", NAME, defgateway);475 479 } 476 480 … … 478 482 } 479 483 480 static int ip_device_req_local(int il_phone, device_id_t device_id, 481 services_t netif) 482 { 483 ip_netif_t *ip_netif; 484 ip_route_t *route; 485 int index; 486 int rc; 487 488 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 489 if (!ip_netif) 490 return ENOMEM; 491 492 rc = ip_routes_initialize(&ip_netif->routes); 493 if (rc != EOK) { 494 free(ip_netif); 495 return rc; 496 } 497 498 ip_netif->device_id = device_id; 499 ip_netif->service = netif; 500 ip_netif->state = NETIF_STOPPED; 484 /** Updates the device content length according to the new MTU value. 485 * 486 * @param[in] device_id The device identifier. 487 * @param[in] mtu The new mtu value. 488 * @return EOK on success. 489 * @return ENOENT if device is not found. 490 */ 491 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu) 492 { 493 ip_netif_t *netif; 501 494 502 495 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 503 504 rc = ip_netif_initialize(ip_netif); 505 if (rc != EOK) { 496 netif = ip_netifs_find(&ip_globals.netifs, device_id); 497 if (!netif) { 506 498 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 507 ip_routes_destroy(&ip_netif->routes); 508 free(ip_netif); 509 return rc; 510 } 511 if (ip_netif->arp) 512 ip_netif->arp->usage++; 513 514 // print the settings 515 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 516 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, 517 ip_netif->dhcp ? "dhcp" : "static"); 518 519 // TODO ipv6 addresses 520 521 char address[INET_ADDRSTRLEN]; 522 char netmask[INET_ADDRSTRLEN]; 523 char gateway[INET_ADDRSTRLEN]; 524 525 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 526 route = ip_routes_get_index(&ip_netif->routes, index); 527 if (route) { 528 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 529 address, INET_ADDRSTRLEN); 530 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 531 netmask, INET_ADDRSTRLEN); 532 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 533 gateway, INET_ADDRSTRLEN); 534 printf("%s: Route %d (address: %s, netmask: %s, " 535 "gateway: %s)\n", NAME, index, address, netmask, 536 gateway); 537 } 538 } 539 540 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 541 INET_ADDRSTRLEN); 499 return ENOENT; 500 } 501 netif->packet_dimension.content = mtu; 542 502 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 543 503 544 printf("%s: Broadcast (%s)\n", NAME, address);504 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu); 545 505 546 506 return EOK; 547 507 } 548 508 549 /** Searches the network interfaces if there is a suitable route. 550 * 551 * @param[in] netif The network interface to be searched for routes. May be 552 * NULL. 553 * @param[in] destination The destination address. 554 * @return The found route. 555 * @return NULL if no route was found. 556 */ 557 static ip_route_t *ip_netif_find_route(ip_netif_t *netif, 558 in_addr_t destination) 559 { 560 int index; 561 ip_route_t *route; 562 563 if (!netif) 509 /** Updates the device state. 510 * 511 * @param[in] device_id The device identifier. 512 * @param[in] state The new state value. 513 * @return EOK on success. 514 * @return ENOENT if device is not found. 515 */ 516 static int ip_device_state_message(device_id_t device_id, device_state_t state) 517 { 518 ip_netif_t *netif; 519 520 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 521 // find the device 522 netif = ip_netifs_find(&ip_globals.netifs, device_id); 523 if (!netif) { 524 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 525 return ENOENT; 526 } 527 netif->state = state; 528 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 529 530 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 531 532 return EOK; 533 } 534 535 536 /** Prefixes a middle fragment header based on the last fragment header to the 537 * packet. 538 * 539 * @param[in] packet The packet to be prefixed. 540 * @param[in] last The last header to be copied. 541 * @return The prefixed middle header. 542 * @return NULL on error. 543 */ 544 static ip_header_t * 545 ip_create_middle_header(packet_t *packet, ip_header_t *last) 546 { 547 ip_header_t *middle; 548 549 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last)); 550 if (!middle) 564 551 return NULL; 565 566 /* Start with the first one (the direct route) */ 567 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 568 route = ip_routes_get_index(&netif->routes, index); 569 if ((route) && 570 ((route->address.s_addr & route->netmask.s_addr) == 571 (destination.s_addr & route->netmask.s_addr))) 572 return route; 573 } 574 575 return NULL; 576 } 577 578 /** Searches all network interfaces if there is a suitable route. 579 * 580 * @param[in] destination The destination address. 581 * @return The found route. 582 * @return NULL if no route was found. 583 */ 584 static ip_route_t *ip_find_route(in_addr_t destination) { 585 int index; 586 ip_route_t *route; 587 ip_netif_t *netif; 588 589 // start with the last netif - the newest one 590 index = ip_netifs_count(&ip_globals.netifs) - 1; 591 while (index >= 0) { 592 netif = ip_netifs_get_index(&ip_globals.netifs, index); 593 if (netif && (netif->state == NETIF_ACTIVE)) { 594 route = ip_netif_find_route(netif, destination); 595 if (route) 596 return route; 597 } 598 index--; 599 } 600 601 return &ip_globals.gateway; 602 } 603 604 /** Returns the network interface's IP address. 605 * 606 * @param[in] netif The network interface. 607 * @return The IP address. 608 * @return NULL if no IP address was found. 609 */ 610 static in_addr_t *ip_netif_address(ip_netif_t *netif) 611 { 612 ip_route_t *route; 613 614 route = ip_routes_get_index(&netif->routes, 0); 615 return route ? &route->address : NULL; 552 memcpy(middle, last, IP_HEADER_LENGTH(last)); 553 middle->flags |= IPFLAG_MORE_FRAGMENTS; 554 return middle; 616 555 } 617 556 … … 682 621 * function. 683 622 */ 684 static int ip_prepare_packet(in_addr_t *source, in_addr_t dest, 685 packet_t *packet, measured_string_t *destination) 623 static int 624 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet, 625 measured_string_t *destination) 686 626 { 687 627 size_t length; … … 699 639 if (destination) { 700 640 rc = packet_set_addr(packet, NULL, (uint8_t *) destination->value, 701 destination->length);641 CONVERT_SIZE(char, uint8_t, destination->length)); 702 642 } else { 703 643 rc = packet_set_addr(packet, NULL, NULL, 0); … … 747 687 rc = packet_set_addr(next, NULL, 748 688 (uint8_t *) destination->value, 749 destination->length); 689 CONVERT_SIZE(char, uint8_t, 690 destination->length)); 750 691 if (rc != EOK) { 751 692 free(last_header); … … 777 718 rc = packet_set_addr(next, NULL, 778 719 (uint8_t *) destination->value, 779 destination->length);720 CONVERT_SIZE(char, uint8_t, destination->length)); 780 721 if (rc != EOK) { 781 722 free(last_header); … … 812 753 * function. 813 754 */ 814 static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 755 static int 756 ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 815 757 ip_header_t *header, ip_header_t *new_header, size_t length, 816 758 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen) … … 846 788 847 789 return pq_insert_after(packet, new_packet); 848 }849 850 /** Prefixes a middle fragment header based on the last fragment header to the851 * packet.852 *853 * @param[in] packet The packet to be prefixed.854 * @param[in] last The last header to be copied.855 * @return The prefixed middle header.856 * @return NULL on error.857 */858 static ip_header_t *ip_create_middle_header(packet_t *packet,859 ip_header_t *last)860 {861 ip_header_t *middle;862 863 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));864 if (!middle)865 return NULL;866 memcpy(middle, last, IP_HEADER_LENGTH(last));867 middle->flags |= IPFLAG_MORE_FRAGMENTS;868 return middle;869 790 } 870 791 … … 1071 992 * function. 1072 993 */ 1073 static int ip_send_route(packet_t *packet, ip_netif_t *netif, 1074 ip_route_t *route, in_addr_t *src, in_addr_t dest, services_t error) 994 static int 995 ip_send_route(packet_t *packet, ip_netif_t *netif, ip_route_t *route, 996 in_addr_t *src, in_addr_t dest, services_t error) 1075 997 { 1076 998 measured_string_t destination; 1077 999 measured_string_t *translation; 1078 uint8_t*data;1000 char *data; 1079 1001 int phone; 1080 1002 int rc; … … 1083 1005 if (netif->arp && (route->address.s_addr != dest.s_addr)) { 1084 1006 destination.value = route->gateway.s_addr ? 1085 ( uint8_t *) &route->gateway.s_addr : (uint8_t*) &dest.s_addr;1086 destination.length = sizeof(dest.s_addr);1007 (char *) &route->gateway.s_addr : (char *) &dest.s_addr; 1008 destination.length = CONVERT_SIZE(dest.s_addr, char, 1); 1087 1009 1088 1010 rc = arp_translate_req(netif->arp->phone, netif->device_id, … … 1135 1057 } 1136 1058 1137 static int ip_send_msg_local(int il_phone, device_id_t device_id, 1138 packet_t *packet, services_t sender, services_t error) 1059 /** Searches the network interfaces if there is a suitable route. 1060 * 1061 * @param[in] netif The network interface to be searched for routes. May be 1062 * NULL. 1063 * @param[in] destination The destination address. 1064 * @return The found route. 1065 * @return NULL if no route was found. 1066 */ 1067 static ip_route_t * 1068 ip_netif_find_route(ip_netif_t *netif, in_addr_t destination) 1069 { 1070 int index; 1071 ip_route_t *route; 1072 1073 if (!netif) 1074 return NULL; 1075 1076 // start with the first one - the direct route 1077 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 1078 route = ip_routes_get_index(&netif->routes, index); 1079 if (route && 1080 ((route->address.s_addr & route->netmask.s_addr) == 1081 (destination.s_addr & route->netmask.s_addr))) { 1082 return route; 1083 } 1084 } 1085 1086 return NULL; 1087 } 1088 1089 /** Searches all network interfaces if there is a suitable route. 1090 * 1091 * @param[in] destination The destination address. 1092 * @return The found route. 1093 * @return NULL if no route was found. 1094 */ 1095 static ip_route_t *ip_find_route(in_addr_t destination) { 1096 int index; 1097 ip_route_t *route; 1098 ip_netif_t *netif; 1099 1100 // start with the last netif - the newest one 1101 index = ip_netifs_count(&ip_globals.netifs) - 1; 1102 while (index >= 0) { 1103 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1104 if (netif && (netif->state == NETIF_ACTIVE)) { 1105 route = ip_netif_find_route(netif, destination); 1106 if (route) 1107 return route; 1108 } 1109 index--; 1110 } 1111 1112 return &ip_globals.gateway; 1113 } 1114 1115 /** Returns the network interface's IP address. 1116 * 1117 * @param[in] netif The network interface. 1118 * @return The IP address. 1119 * @return NULL if no IP address was found. 1120 */ 1121 static in_addr_t *ip_netif_address(ip_netif_t *netif) 1122 { 1123 ip_route_t *route; 1124 1125 route = ip_routes_get_index(&netif->routes, 0); 1126 return route ? &route->address : NULL; 1127 } 1128 1129 /** Registers the transport layer protocol. 1130 * 1131 * The traffic of this protocol will be supplied using either the receive 1132 * function or IPC message. 1133 * 1134 * @param[in] protocol The transport layer module protocol. 1135 * @param[in] service The transport layer module service. 1136 * @param[in] phone The transport layer module phone. 1137 * @param[in] received_msg The receiving function. 1138 * @return EOK on success. 1139 * @return EINVAL if the protocol parameter and/or the service 1140 * parameter is zero. 1141 * @return EINVAL if the phone parameter is not a positive number 1142 * and the tl_receive_msg is NULL. 1143 * @return ENOMEM if there is not enough memory left. 1144 */ 1145 static int 1146 ip_register(int protocol, services_t service, int phone, 1147 tl_received_msg_t received_msg) 1148 { 1149 ip_proto_t *proto; 1150 int index; 1151 1152 if (!protocol || !service || ((phone < 0) && !received_msg)) 1153 return EINVAL; 1154 1155 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t)); 1156 if (!proto) 1157 return ENOMEM; 1158 1159 proto->protocol = protocol; 1160 proto->service = service; 1161 proto->phone = phone; 1162 proto->received_msg = received_msg; 1163 1164 fibril_rwlock_write_lock(&ip_globals.protos_lock); 1165 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 1166 if (index < 0) { 1167 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1168 free(proto); 1169 return index; 1170 } 1171 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1172 1173 printf("%s: Protocol registered (protocol: %d, phone: %d)\n", 1174 NAME, proto->protocol, proto->phone); 1175 1176 return EOK; 1177 } 1178 1179 static int 1180 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif) 1181 { 1182 ip_netif_t *ip_netif; 1183 ip_route_t *route; 1184 int index; 1185 int rc; 1186 1187 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 1188 if (!ip_netif) 1189 return ENOMEM; 1190 1191 rc = ip_routes_initialize(&ip_netif->routes); 1192 if (rc != EOK) { 1193 free(ip_netif); 1194 return rc; 1195 } 1196 1197 ip_netif->device_id = device_id; 1198 ip_netif->service = netif; 1199 ip_netif->state = NETIF_STOPPED; 1200 1201 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1202 1203 rc = ip_netif_initialize(ip_netif); 1204 if (rc != EOK) { 1205 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1206 ip_routes_destroy(&ip_netif->routes); 1207 free(ip_netif); 1208 return rc; 1209 } 1210 if (ip_netif->arp) 1211 ip_netif->arp->usage++; 1212 1213 // print the settings 1214 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 1215 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, 1216 ip_netif->dhcp ? "dhcp" : "static"); 1217 1218 // TODO ipv6 addresses 1219 1220 char address[INET_ADDRSTRLEN]; 1221 char netmask[INET_ADDRSTRLEN]; 1222 char gateway[INET_ADDRSTRLEN]; 1223 1224 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 1225 route = ip_routes_get_index(&ip_netif->routes, index); 1226 if (route) { 1227 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 1228 address, INET_ADDRSTRLEN); 1229 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 1230 netmask, INET_ADDRSTRLEN); 1231 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 1232 gateway, INET_ADDRSTRLEN); 1233 printf("%s: Route %d (address: %s, netmask: %s, " 1234 "gateway: %s)\n", NAME, index, address, netmask, 1235 gateway); 1236 } 1237 } 1238 1239 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 1240 INET_ADDRSTRLEN); 1241 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1242 1243 printf("%s: Broadcast (%s)\n", NAME, address); 1244 1245 return EOK; 1246 } 1247 1248 static int 1249 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet, 1250 services_t sender, services_t error) 1139 1251 { 1140 1252 int addrlen; … … 1177 1289 if (device_id > 0) { 1178 1290 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1179 route = ip_netif_find_route(netif, * dest);1291 route = ip_netif_find_route(netif, * dest); 1180 1292 if (netif && !route && (ip_globals.gateway.netif == netif)) 1181 1293 route = &ip_globals.gateway; … … 1207 1319 } 1208 1320 } 1209 1321 1210 1322 // if the local host is the destination 1211 1323 if ((route->address.s_addr == dest->s_addr) && … … 1240 1352 } 1241 1353 1242 /** Updates the device state. 1243 * 1354 /** Returns the device packet dimensions for sending. 1355 * 1356 * @param[in] phone The service module phone. 1357 * @param[in] message The service specific message. 1244 1358 * @param[in] device_id The device identifier. 1245 * @param[in] state The new state value. 1359 * @param[out] addr_len The minimum reserved address length. 1360 * @param[out] prefix The minimum reserved prefix size. 1361 * @param[out] content The maximum content size. 1362 * @param[out] suffix The minimum reserved suffix size. 1246 1363 * @return EOK on success. 1247 * @return ENOENT if device is not found. 1248 */ 1249 static int ip_device_state_message(device_id_t device_id, device_state_t state) 1364 */ 1365 static int 1366 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix, 1367 size_t *content, size_t *suffix) 1250 1368 { 1251 1369 ip_netif_t *netif; 1252 1253 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1254 // find the device 1255 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1256 if (!netif) { 1257 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1258 return ENOENT; 1259 } 1260 netif->state = state; 1261 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1262 1263 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 1370 int index; 1371 1372 if (!addr_len || !prefix || !content || !suffix) 1373 return EBADMEM; 1374 1375 *content = IP_MAX_CONTENT - IP_PREFIX; 1376 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1377 if (device_id < 0) { 1378 *addr_len = IP_ADDR; 1379 *prefix = 0; 1380 *suffix = 0; 1381 1382 for (index = ip_netifs_count(&ip_globals.netifs) - 1; 1383 index >= 0; index--) { 1384 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1385 if (!netif) 1386 continue; 1387 1388 if (netif->packet_dimension.addr_len > *addr_len) 1389 *addr_len = netif->packet_dimension.addr_len; 1390 1391 if (netif->packet_dimension.prefix > *prefix) 1392 *prefix = netif->packet_dimension.prefix; 1393 1394 if (netif->packet_dimension.suffix > *suffix) 1395 *suffix = netif->packet_dimension.suffix; 1396 } 1397 1398 *prefix = *prefix + IP_PREFIX; 1399 *suffix = *suffix + IP_SUFFIX; 1400 } else { 1401 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1402 if (!netif) { 1403 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1404 return ENOENT; 1405 } 1406 1407 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ? 1408 netif->packet_dimension.addr_len : IP_ADDR; 1409 *prefix = netif->packet_dimension.prefix + IP_PREFIX; 1410 *suffix = netif->packet_dimension.suffix + IP_SUFFIX; 1411 } 1412 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1264 1413 1265 1414 return EOK; … … 1301 1450 * tl_received_msg() function. 1302 1451 */ 1303 static int ip_deliver_local(device_id_t device_id, packet_t *packet, 1304 ip_header_t *header, services_t error) 1452 static int 1453 ip_deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header, 1454 services_t error) 1305 1455 { 1306 1456 ip_proto_t *proto; … … 1402 1552 * is disabled. 1403 1553 */ 1404 static int ip_process_packet(device_id_t device_id, packet_t *packet) 1554 static int 1555 ip_process_packet(device_id_t device_id, packet_t *packet) 1405 1556 { 1406 1557 ip_header_t *header; … … 1412 1563 socklen_t addrlen; 1413 1564 int rc; 1414 1565 1415 1566 header = (ip_header_t *) packet_get_data(packet); 1416 1567 if (!header) … … 1438 1589 return EINVAL; 1439 1590 } 1440 1591 1441 1592 // process ipopt and get destination 1442 1593 dest = ip_get_destination(header); … … 1459 1610 if (rc != EOK) 1460 1611 return rc; 1461 1612 1462 1613 route = ip_find_route(dest); 1463 1614 if (!route) { … … 1491 1642 return ENOENT; 1492 1643 } 1493 1494 /** Returns the device packet dimensions for sending.1495 *1496 * @param[in] phone The service module phone.1497 * @param[in] message The service specific message.1498 * @param[in] device_id The device identifier.1499 * @param[out] addr_len The minimum reserved address length.1500 * @param[out] prefix The minimum reserved prefix size.1501 * @param[out] content The maximum content size.1502 * @param[out] suffix The minimum reserved suffix size.1503 * @return EOK on success.1504 */1505 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,1506 size_t *prefix, size_t *content, size_t *suffix)1507 {1508 ip_netif_t *netif;1509 int index;1510 1511 if (!addr_len || !prefix || !content || !suffix)1512 return EBADMEM;1513 1514 *content = IP_MAX_CONTENT - IP_PREFIX;1515 fibril_rwlock_read_lock(&ip_globals.netifs_lock);1516 if (device_id < 0) {1517 *addr_len = IP_ADDR;1518 *prefix = 0;1519 *suffix = 0;1520 1521 for (index = ip_netifs_count(&ip_globals.netifs) - 1;1522 index >= 0; index--) {1523 netif = ip_netifs_get_index(&ip_globals.netifs, index);1524 if (!netif)1525 continue;1526 1527 if (netif->packet_dimension.addr_len > *addr_len)1528 *addr_len = netif->packet_dimension.addr_len;1529 1530 if (netif->packet_dimension.prefix > *prefix)1531 *prefix = netif->packet_dimension.prefix;1532 1533 if (netif->packet_dimension.suffix > *suffix)1534 *suffix = netif->packet_dimension.suffix;1535 }1536 1537 *prefix = *prefix + IP_PREFIX;1538 *suffix = *suffix + IP_SUFFIX;1539 } else {1540 netif = ip_netifs_find(&ip_globals.netifs, device_id);1541 if (!netif) {1542 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);1543 return ENOENT;1544 }1545 1546 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?1547 netif->packet_dimension.addr_len : IP_ADDR;1548 *prefix = netif->packet_dimension.prefix + IP_PREFIX;1549 *suffix = netif->packet_dimension.suffix + IP_SUFFIX;1550 }1551 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);1552 1553 return EOK;1554 }1555 1556 /** Updates the device content length according to the new MTU value.1557 *1558 * @param[in] device_id The device identifier.1559 * @param[in] mtu The new mtu value.1560 * @return EOK on success.1561 * @return ENOENT if device is not found.1562 */1563 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)1564 {1565 ip_netif_t *netif;1566 1567 fibril_rwlock_write_lock(&ip_globals.netifs_lock);1568 netif = ip_netifs_find(&ip_globals.netifs, device_id);1569 if (!netif) {1570 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);1571 return ENOENT;1572 }1573 netif->packet_dimension.content = mtu;1574 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);1575 1576 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);1577 1578 return EOK;1579 }1580 1581 /** Process IPC messages from the registered device driver modules1582 *1583 * @param[in] iid Message identifier.1584 * @param[in,out] icall Message parameters.1585 *1586 */1587 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall)1588 {1589 packet_t *packet;1590 int rc;1591 1592 while (true) {1593 switch (IPC_GET_IMETHOD(*icall)) {1594 case NET_IL_DEVICE_STATE:1595 rc = ip_device_state_message(IPC_GET_DEVICE(*icall),1596 IPC_GET_STATE(*icall));1597 async_answer_0(iid, (sysarg_t) rc);1598 break;1599 1600 case NET_IL_RECEIVED:1601 rc = packet_translate_remote(ip_globals.net_phone, &packet,1602 IPC_GET_PACKET(*icall));1603 if (rc == EOK) {1604 do {1605 packet_t *next = pq_detach(packet);1606 ip_process_packet(IPC_GET_DEVICE(*icall), packet);1607 packet = next;1608 } while (packet);1609 }1610 1611 async_answer_0(iid, (sysarg_t) rc);1612 break;1613 1614 case NET_IL_MTU_CHANGED:1615 rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall),1616 IPC_GET_MTU(*icall));1617 async_answer_0(iid, (sysarg_t) rc);1618 break;1619 1620 default:1621 async_answer_0(iid, (sysarg_t) ENOTSUP);1622 }1623 1624 iid = async_get_call(icall);1625 }1626 }1627 1628 /** Registers the transport layer protocol.1629 *1630 * The traffic of this protocol will be supplied using either the receive1631 * function or IPC message.1632 *1633 * @param[in] protocol The transport layer module protocol.1634 * @param[in] service The transport layer module service.1635 * @param[in] phone The transport layer module phone.1636 * @param[in] received_msg The receiving function.1637 * @return EOK on success.1638 * @return EINVAL if the protocol parameter and/or the service1639 * parameter is zero.1640 * @return EINVAL if the phone parameter is not a positive number1641 * and the tl_receive_msg is NULL.1642 * @return ENOMEM if there is not enough memory left.1643 */1644 static int1645 ip_register(int protocol, services_t service, int phone,1646 tl_received_msg_t received_msg)1647 {1648 ip_proto_t *proto;1649 int index;1650 1651 if (!protocol || !service || ((phone < 0) && !received_msg))1652 return EINVAL;1653 1654 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));1655 if (!proto)1656 return ENOMEM;1657 1658 proto->protocol = protocol;1659 proto->service = service;1660 proto->phone = phone;1661 proto->received_msg = received_msg;1662 1663 fibril_rwlock_write_lock(&ip_globals.protos_lock);1664 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);1665 if (index < 0) {1666 fibril_rwlock_write_unlock(&ip_globals.protos_lock);1667 free(proto);1668 return index;1669 }1670 fibril_rwlock_write_unlock(&ip_globals.protos_lock);1671 1672 printf("%s: Protocol registered (protocol: %d, phone: %d)\n",1673 NAME, proto->protocol, proto->phone);1674 1675 return EOK;1676 }1677 1678 1644 1679 1645 static int … … 1791 1757 (header->destination_address & route->netmask.s_addr))) { 1792 1758 // clear the ARP mapping if any 1793 address.value = (uint8_t *) &header->destination_address; 1794 address.length = sizeof(header->destination_address); 1759 address.value = (char *) &header->destination_address; 1760 address.length = CONVERT_SIZE(uint8_t, char, 1761 sizeof(header->destination_address)); 1795 1762 arp_clear_address_req(netif->arp->phone, 1796 1763 netif->device_id, SERVICE_IP, &address); … … 1876 1843 } 1877 1844 1845 /** Processes the received IP packet or the packet queue one by one. 1846 * 1847 * The packet is either passed to another module or released on error. 1848 * 1849 * @param[in] device_id The source device identifier. 1850 * @param[in,out] packet The received packet. 1851 * @return EOK on success and the packet is no longer needed. 1852 * @return EINVAL if the packet is too small to carry the IP 1853 * packet. 1854 * @return EINVAL if the received address lengths differs from the 1855 * registered values. 1856 * @return ENOENT if the device is not found in the cache. 1857 * @return ENOENT if the protocol for the device is not found in 1858 * the cache. 1859 * @return ENOMEM if there is not enough memory left. 1860 */ 1861 static int ip_receive_message(device_id_t device_id, packet_t *packet) 1862 { 1863 packet_t *next; 1864 1865 do { 1866 next = pq_detach(packet); 1867 ip_process_packet(device_id, packet); 1868 packet = next; 1869 } while (packet); 1870 1871 return EOK; 1872 } 1873 1878 1874 /** Processes the IP message. 1879 1875 * … … 1887 1883 * 1888 1884 * @see ip_interface.h 1889 * @see il_ remote.h1885 * @see il_interface.h 1890 1886 * @see IS_NET_IP_MESSAGE() 1891 1887 */ 1892 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1893 size_t *answer_count) 1888 int 1889 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1890 int *answer_count) 1894 1891 { 1895 1892 packet_t *packet; 1896 1893 struct sockaddr *addr; 1897 void *header;1898 size_t headerlen;1899 1894 size_t addrlen; 1900 1895 size_t prefix; 1901 1896 size_t suffix; 1902 1897 size_t content; 1898 void *header; 1899 size_t headerlen; 1903 1900 device_id_t device_id; 1904 1901 int rc; 1905 1902 1906 1903 *answer_count = 0; 1907 switch (IPC_GET_ IMETHOD(*call)) {1904 switch (IPC_GET_METHOD(*call)) { 1908 1905 case IPC_M_PHONE_HUNGUP: 1909 1906 return EOK; 1910 1907 1911 1908 case IPC_M_CONNECT_TO_ME: 1912 return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call), 1913 IPC_GET_PHONE(*call), NULL); 1914 1915 case NET_IP_DEVICE: 1916 return ip_device_req_local(0, IPC_GET_DEVICE(*call), 1917 IPC_GET_SERVICE(*call)); 1909 return ip_register(IL_GET_PROTO(call), IL_GET_SERVICE(call), 1910 IPC_GET_PHONE(call), NULL); 1911 1912 case NET_IL_DEVICE: 1913 return ip_device_req_local(0, IPC_GET_DEVICE(call), 1914 IPC_GET_SERVICE(call)); 1915 1916 case NET_IL_SEND: 1917 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1918 IPC_GET_PACKET(call)); 1919 if (rc != EOK) 1920 return rc; 1921 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0, 1922 IPC_GET_ERROR(call)); 1923 1924 case NET_IL_DEVICE_STATE: 1925 return ip_device_state_message(IPC_GET_DEVICE(call), 1926 IPC_GET_STATE(call)); 1927 1928 case NET_IL_RECEIVED: 1929 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1930 IPC_GET_PACKET(call)); 1931 if (rc != EOK) 1932 return rc; 1933 return ip_receive_message(IPC_GET_DEVICE(call), packet); 1918 1934 1919 1935 case NET_IP_RECEIVED_ERROR: 1920 1936 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1921 IPC_GET_PACKET( *call));1937 IPC_GET_PACKET(call)); 1922 1938 if (rc != EOK) 1923 1939 return rc; 1924 return ip_received_error_msg_local(0, IPC_GET_DEVICE( *call),1925 packet, IPC_GET_TARGET( *call), IPC_GET_ERROR(*call));1940 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call), 1941 packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call)); 1926 1942 1927 1943 case NET_IP_ADD_ROUTE: 1928 return ip_add_route_req_local(0, IPC_GET_DEVICE( *call),1929 IP_GET_ADDRESS( *call), IP_GET_NETMASK(*call),1930 IP_GET_GATEWAY( *call));1944 return ip_add_route_req_local(0, IPC_GET_DEVICE(call), 1945 IP_GET_ADDRESS(call), IP_GET_NETMASK(call), 1946 IP_GET_GATEWAY(call)); 1931 1947 1932 1948 case NET_IP_SET_GATEWAY: 1933 return ip_set_gateway_req_local(0, IPC_GET_DEVICE( *call),1934 IP_GET_GATEWAY( *call));1949 return ip_set_gateway_req_local(0, IPC_GET_DEVICE(call), 1950 IP_GET_GATEWAY(call)); 1935 1951 1936 1952 case NET_IP_GET_ROUTE: 1937 rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, 1938 &addrlen); 1953 rc = data_receive((void **) &addr, &addrlen); 1939 1954 if (rc != EOK) 1940 1955 return rc; 1941 1956 1942 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL( *call), addr,1957 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(call), addr, 1943 1958 (socklen_t) addrlen, &device_id, &header, &headerlen); 1944 1959 if (rc != EOK) 1945 1960 return rc; 1946 1961 1947 IPC_SET_DEVICE( *answer, device_id);1948 IP_SET_HEADERLEN( *answer, headerlen);1962 IPC_SET_DEVICE(answer, device_id); 1963 IP_SET_HEADERLEN(answer, headerlen); 1949 1964 1950 1965 *answer_count = 2; … … 1957 1972 return rc; 1958 1973 1959 case NET_I P_PACKET_SPACE:1960 rc = ip_packet_size_message(IPC_GET_DEVICE( *call), &addrlen,1974 case NET_IL_PACKET_SPACE: 1975 rc = ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen, 1961 1976 &prefix, &content, &suffix); 1962 1977 if (rc != EOK) 1963 1978 return rc; 1964 1979 1965 IPC_SET_ADDR( *answer, addrlen);1966 IPC_SET_PREFIX( *answer, prefix);1967 IPC_SET_CONTENT( *answer, content);1968 IPC_SET_SUFFIX( *answer, suffix);1980 IPC_SET_ADDR(answer, addrlen); 1981 IPC_SET_PREFIX(answer, prefix); 1982 IPC_SET_CONTENT(answer, content); 1983 IPC_SET_SUFFIX(answer, suffix); 1969 1984 *answer_count = 4; 1970 1985 return EOK; 1971 1986 1972 case NET_IP_SEND: 1973 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1974 IPC_GET_PACKET(*call)); 1975 if (rc != EOK) 1976 return rc; 1987 case NET_IL_MTU_CHANGED: 1988 return ip_mtu_changed_message(IPC_GET_DEVICE(call), 1989 IPC_GET_MTU(call)); 1990 } 1991 1992 return ENOTSUP; 1993 } 1994 1995 /** Default thread for new connections. 1996 * 1997 * @param[in] iid The initial message identifier. 1998 * @param[in] icall The initial message call structure. 1999 */ 2000 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall) 2001 { 2002 /* 2003 * Accept the connection 2004 * - Answer the first IPC_M_CONNECT_ME_TO call. 2005 */ 2006 ipc_answer_0(iid, EOK); 2007 2008 while (true) { 2009 ipc_call_t answer; 2010 int answer_count; 1977 2011 1978 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0, 1979 IPC_GET_ERROR(*call)); 1980 } 1981 1982 return ENOTSUP; 1983 } 1984 2012 /* Clear the answer structure */ 2013 refresh_answer(&answer, &answer_count); 2014 2015 /* Fetch the next message */ 2016 ipc_call_t call; 2017 ipc_callid_t callid = async_get_call(&call); 2018 2019 /* Process the message */ 2020 int res = il_module_message_standalone(callid, &call, &answer, 2021 &answer_count); 2022 2023 /* 2024 * End if told to either by the message or the processing 2025 * result. 2026 */ 2027 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 2028 (res == EHANGUP)) { 2029 return; 2030 } 2031 2032 /* Answer the message */ 2033 answer_call(callid, res, &answer, answer_count); 2034 } 2035 } 2036 2037 /** Starts the module. 2038 * 2039 * @return EOK on success. 2040 * @return Other error codes as defined for each specific module start function. 2041 */ 1985 2042 int main(int argc, char *argv[]) 1986 2043 { 2044 int rc; 2045 1987 2046 /* Start the module */ 1988 return il_module_start(SERVICE_IP); 2047 rc = il_module_start_standalone(il_client_connection); 2048 return rc; 1989 2049 } 1990 2050
Note:
See TracChangeset
for help on using the changeset viewer.